Git Server

ํ”„๋กœํ† ์ฝœ

Git์€ Local, SSH, Git, HTTP ์ด๋ ‡๊ฒŒ ๋„ค ๊ฐ€์ง€์˜ ๋„คํŠธ์›Œํฌ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ์ ˆ์—์„œ๋Š” ๊ฐ๊ฐ ์–ด๋–ค ๊ฒฝ์šฐ์— ์œ ์šฉํ•œ์ง€ ์‚ดํŽด๋ณผ ๊ฒƒ์ด๋‹ค.

HTTP ํ”„๋กœํ† ์ฝœ์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€๋“ค์€ ๋ชจ๋‘ Git์ด ์„œ๋ฒ„์— ์„ค์น˜๋ผ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

๋กœ์ปฌ ํ”„๋กœํ† ์ฝœ

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ฒƒ์ด ๋กœ์ปฌ ํ”„๋กœํ† ์ฝœ ์ด๋‹ค. ๋ฆฌ๋ชจํŠธ ์ €์žฅ์†Œ๊ฐ€ ๋‹จ์ˆœํžˆ ๋””์Šคํฌ์˜ ๋‹ค๋ฅธ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ํŒ€์›๋“ค์ด ์ „๋ถ€ ํ•œ ์‹œ์Šคํ…œ์— ๋กœ๊ทธ์ธํ•˜์—ฌ ๊ฐœ๋ฐœํ•˜๊ฑฐ๋‚˜ ์•„๋‹ˆ๋ฉด NFS๊ฐ™์€ ๊ฒƒ์œผ๋กœ ํŒŒ์ผ์‹œ์Šคํ…œ์„ ๊ณต์œ ํ•˜๊ณ  ์žˆ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์ „์ž๋Š” ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. ๋ชจ๋“  ์ €์žฅ์†Œ๊ฐ€ ํ•œ ์‹œ์Šคํ…œ์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•œ์ˆœ๊ฐ„์— ๋ชจ๋‘ ์žƒ์„ ์ˆ˜ ์žˆ๋‹ค.

๊ณต์œ  ํŒŒ์ผ์‹œ์Šคํ…œ์„ ๋งˆ์šดํŠธํ–ˆ์„ ๋•Œ๋Š” ๋กœ์ปฌ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Cloneํ•˜๊ณ  Pushํ•˜๊ณ  Pullํ•˜๋ฉด ๋œ๋‹ค. ์ผ๋‹จ ์ €์žฅ์†Œ๋ฅผ Cloneํ•˜๊ฑฐ๋‚˜ ํ”„๋กœ์ ํŠธ์— ๋ฆฌ๋ชจํŠธ ์ €์žฅ์†Œ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ถ”๊ฐ€ํ•  ๋•Œ URL ์ž๋ฆฌ์— ์ €์žฅ์†Œ์˜ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ๋กœ์ปฌ ์ €์žฅ์†Œ๋ฅผ Cloneํ•œ๋‹ค:

$ git clone /opt/git/project.git

์•„๋ž˜ ์ฒ˜๋Ÿผ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค:

$ git clone file:///opt/git/project.git

Git์€ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ง์ ‘ ์“ธ ๋•Œ์™€ file://๋กœ ์‹œ์ž‘ํ•˜๋Š” URL์„ ์‚ฌ์šฉํ•  ๋•Œ์— ์•ฝ๊ฐ„ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•œ๋‹ค. ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ™์€ ํŒŒ์ผ์‹œ์Šคํ…œ์— ์žˆ๋Š” ์ €์žฅ์†Œ๋ฅผ Cloneํ•  ๋•Œ Git์€ ํ•˜๋“œ๋งํฌ๋ฅผ ๋งŒ๋“ ๋‹ค. ๊ฐ™์€ ํŒŒ์ผ์‹œ์Šคํ…œ์— ์žˆ๋Š”๊ฒŒ ์•„๋‹ˆ๋ฉด ๊ทธ๋ƒฅ ๋ณต์‚ฌํ•œ๋‹ค. ํ•˜์ง€๋งŒ file://๋กœ ์‹œ์ž‘ํ•˜๋ฉด Git์€ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ๋•Œ์ฒ˜๋Ÿผ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ณ„๋„๋กœ ์ƒ์„ฑํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ด ํ”„๋กœ์„ธ์Šค๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๊ฒƒ์€ ํšจ์œจ์ด ์ข€ ๋–จ์–ด์ง€์ง€๋งŒ ๊ทธ๋ž˜๋„ file://๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๊ฐ€ ์žˆ๋‹ค. ๋ณดํ†ต์€ ๋‹ค๋ฅธ ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ๋“ค์—์„œ ์ž„ํฌํŠธํ•œ ํ›„์— ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์™ธ๋ถ€ ๋ ˆํผ๋Ÿฐ์Šค๋‚˜ ๊ฐœ์ฒด๋“ค์ด ํฌํ•จ๋œ ์ €์žฅ์†Œ์˜ ๋ณต์‚ฌ๋ณธ์„ ๊นจ๋—ํ•œ ์ƒํƒœ๋กœ ๋‚จ๊ฒจ๋‘๊ณ ์ž ํ• ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค(_9์žฅ_์—์„œ ์ž์„ธํžˆ ๋‹ค๋ฃฌ๋‹ค). ์—ฌ๊ธฐ์„œ๋Š” ์†๋„๊ฐ€ ๋น ๋ฅธ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์ด๋ฏธ ์žˆ๋Š” Git ํ”„๋กœ์ ํŠธ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ๋กœ์ปฌ ์ €์žฅ์†Œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค:

$ git remote add local_proj /opt/git/project.git

๊ทธ๋Ÿฌ๋ฉด ๋„คํŠธ์›Œํฌ์— ์žˆ๋Š” ๋ฆฌ๋ชจํŠธ ์ €์žฅ์†Œ์ฒ˜๋Ÿผ Pushํ•˜๊ณ  Pullํ•  ์ˆ˜ ์žˆ๋‹ค.

์žฅ์ 

ํŒŒ์ผ ๊ธฐ๋ฐ˜ ์ €์žฅ์†Œ๋Š” ๋‹จ์ˆœํ•œ ๊ฒƒ์ด ์žฅ์ ์ด๋‹ค. ๊ธฐ์กด์— ์žˆ๋˜ ๋„คํŠธ์›Œํฌ๋‚˜ ํŒŒ์ผ์˜ ๊ถŒํ•œ์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ค์ •ํ•˜๊ธฐ ์‰ฝ๋‹ค. ์ด๋ฏธ ํŒ€ ์ „์ฒด๊ฐ€ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ํŒŒ์ผ์‹œ์Šคํ…œ์ด ์žˆ์œผ๋ฉด ์ €์žฅ์†Œ๋ฅผ ์•„์ฃผ ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๋“ฏ์ด ๋™๋ฃŒ๊ฐ€ ๋ชจ๋‘ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ณต์œ  ๋””๋ ‰ํ† ๋ฆฌ์— Bare ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ ๋‹ค. ๋‹ค์Œ ์ ˆ์ธ "์„œ๋ฒ„์— Git ์„ค์น˜ํ•˜๊ธฐ"์—์„œ Bare ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณผ ๊ฒƒ์ด๋‹ค.

๋˜ํ•œ, ๋™๋ฃŒ๊ฐ€ ์ž‘์—…ํ•˜๋Š” ์ €์žฅ์†Œ์—์„œ ํ•œ ์ผ์„ ๋ฐ”๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ์—๋„ ์ข‹๋‹ค. ๋งŒ์•ฝ ํ•จ๊ป˜ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋Š” ๋™๋ฃŒ๊ฐ€ ์ž์‹ ์ด ํ•œ ์ผ์„ ๋‹น์‹ ์ด ํ™•์ธํ•ด ์คฌ์œผ๋ฉด ํ•œ๋‹ค. ์ด๋Ÿด ๋•Œ ๊ทธ ๋™๋ฃŒ๊ฐ€ ์„œ๋ฒ„์— Pushํ•˜๊ณ  ๋‹น์‹ ์ด ๋‹ค์‹œ Pullํ•  ํ•„์š”์—†์ด git pull /home/john/project ๋ผ๋Š” ๋ช…๋ น์–ด๋ฅผ ๋ฐ”๋กœ ์‹คํ–‰์‹œ์ผœ์„œ ๋งค์šฐ ์‰ฝ๊ฒŒ ๋™๋ฃŒ์˜ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

๋‹จ์ 

๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์–ด๋ ต๋‹ค. ์ง‘์— ์žˆ์„ ๋•Œ Pushํ•˜๋ ค๋ฉด ๋ฆฌ๋ชจํŠธ ์ €์žฅ์†Œ๊ฐ€ ์žˆ๋Š” ๋””์Šคํฌ๋ฅผ ๋งˆ์šดํŠธํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ด๊ฒƒ์€ ๋‹ค๋ฅธ ํ”„๋กœํ† ์ฝœ์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋ณด๋‹ค ๋Š๋ฆฌ๊ณ  ์–ด๋ ต๋‹ค.

๊ฒŒ๋‹ค๊ฐ€ ๋„คํŠธ์›Œํฌ ํŒŒ์ผ์‹œ์Šคํ…œ์„ ๋งˆ์šดํŠธํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ์ค‘์ด๋ผ๋ฉด ๋ณ„๋กœ ๋น ๋ฅด์ง€๋„ ์•Š๋‹ค. ๋กœ์ปฌ ์ €์žฅ์†Œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ์„ ๋•Œ๋งŒ ๋น ๋ฅด๋‹ค. NFS์— ์žˆ๋Š” ์ €์žฅ์†Œ์— Git์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ณดํ†ต ๊ฐ™์€ ์„œ๋ฒ„์— SSH๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋Š๋ฆฌ๋‹ค.

SSH ํ”„๋กœํ† ์ฝœ

Git์˜ ๋Œ€ํ‘œ ํ”„๋กœํ† ์ฝœ์€ SSH์ด๋‹ค. ๋Œ€๋ถ€๋ถ„ ์„œ๋ฒ„๋Š” SSH๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •๋ผ ์žˆ๋‹ค. ๋ญ, ์„ค์ •๋ผ ์žˆ์ง€ ์•Š๋”๋ผ๋„ ์‰ฝ๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  SSH๋Š” ์ฝ๊ธฐ/์“ฐ๊ธฐ ์ ‘๊ทผ์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๋„คํŠธ์›Œํฌ ํ”„๋กœํ† ์ฝœ์ด๋‹ค. ๋‹ค๋ฅธ ๋„คํŠธ์›Œํฌ ํ”„๋กœํ† ์ฝœ์ธ HTTP์™€ Git์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค. ๊ทธ๋ž˜์„œ ์ดˆ๋ณด์ž(unwashed masses)๋ผ๊ณ  ํ•ด๋„ ์“ฐ๊ธฐ ๋ช…๋ น์„ ์ด์šฉํ•˜๋ ค๋ฉด SSH๊ฐ€ ํ•„์š”ํ•˜๋‹ค. SSH๋Š” ๋˜ํ•œ ์ธ์ฆ๋„ ์ง€์›ํ•œ๋‹ค. SSH๋Š” ๋ณดํ†ต ์œ ๋น„์ฟผํ„ฐ์Šค ์ ์ด๋ฉด์„œ๋„, ์‚ฌ์šฉํ•˜๊ธฐ๋„, ์„ค์น˜ํ•˜๊ธฐ๋„ ์‰ฝ๋‹ค.

SSH๋ฅผ ํ†ตํ•ด Git ์ €์žฅ์†Œ๋ฅผ Cloneํ•˜๋ ค๋ฉด ssh://๋กœ ์‹œ์ž‘ํ•˜๋Š” URL์„ ์‚ฌ์šฉํ•œ๋‹ค:

$ git clone ssh://user@server/project.git

์•„๋‹ˆ๋ฉด scp ๋ช…๋ น์–ด์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒŒ ์กฐ๊ธˆ ๋” ์งง๋‹ค:

$ git clone user@server:project.git

์‚ฌ์šฉ์ž ๊ณ„์ •์„ ์ƒ๋žตํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ ๊ณ„์ •์„ ์ƒ๋žตํ•˜๋ฉด Git์€ ํ˜„์žฌ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ๊ณ„์ •์„ ์‚ฌ์šฉํ•œ๋‹ค.

์žฅ์ 

SSH๋Š” ์žฅ์ ์ด ๋งค์šฐ ๋งŽ์€ ํ”„๋กœํ† ์ฝœ์ด๋‹ค. ์ฒซ์งธ, ๋ˆ„๊ฐ€ ๋ฆฌ๋ชจํŠธ์—์„œ ์ €์žฅ์†Œ์— ์ ‘๊ทผํ•˜๋Š”์ง€ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด SSH๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๋‘˜์งธ, SSH๋Š” ์ƒ๋Œ€์ ์œผ๋กœ ์„ค์ •ํ•˜๊ธฐ ์‰ฝ๋‹ค. SSH ๋ฐ๋ชฌ์€ ์ •๋ง ํ”ํ•˜๋‹ค. ๊ฑฐ์˜ ๋ชจ๋“  ๋„คํŠธ์›Œํฌ ๊ด€๋ฆฌ์ž๋Š” SSH ๋ฐ๋ชฌ์„ ๋‹ค๋ฃจ์–ด๋ณธ ๊ฒฝํ—˜์„ ๊ฐ€์ง€๊ณ  ์žˆ์„๊ฒƒ์ด๊ณ , ๋Œ€๋ถ€๋ถ„์˜ OS ๋ฐฐํฌํŒ์—๋Š” SSH ๋ฐ๋ชฌ๊ณผ ๊ด€๋ฆฌ๋„๊ตฌ๊ฐ€ ๋“ค์–ด ์žˆ๋‹ค. ์…‹์งธ, SSH๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•˜๋ฉด ๋ณด์•ˆ์— ์•ˆ์ „ํ•˜๋‹ค. ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋Š” ์•”ํ˜ธํ™”๋˜์–ด ์ธ์ฆ๋œ ์ƒํƒœ๋กœ ์ „์†ก๋œ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ SSH๋Š” ์ „์†ก ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๋Šฅํ•œ ์••์ถ•ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํšจ์œจ์ ์ด๋‹ค.

๋‹จ์ 

SSH์˜ ๋‹จ์ ์€ ์ต๋ช…์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์‹ฌ์ง€์–ด ์ฝ๊ธฐ ์ „์šฉ์ธ ๊ฒฝ์šฐ์—๋„ ์ต๋ช…์œผ๋กœ ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. ํšŒ์‚ฌ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๋ฉด SSH๊ฐ€ ๊ฐ€์žฅ ์ ํ•ฉํ•œ ํ”„๋กœํ† ์ฝœ์ผ ๊ฒƒ์ด์ง€๋งŒ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ๋Š” SSH๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•˜๋‹ค. ๋งŒ์•ฝ ์‚ฌ๋žŒ๋“ค์ด ํ”„๋กœ์ ํŠธ์— ์ต๋ช…์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด, ์ž์‹ ์ด Pushํ•  ๋•Œ ์‚ฌ์šฉํ•  SSH๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๋ณ„๊ฐœ๋กœ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด Pullํ•  ๋•Œ ์‚ฌ์šฉํ•  ๋‹ค๋ฅธ ํ”„๋กœํ† ์ฝœ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

Git ํ”„๋กœํ† ์ฝœ

Git ํ”„๋กœํ† ์ฝœ์€ Git์— ํฌํ•จ๋œ ๋ฐ๋ชฌ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ํฌํŠธ๋Š” 9418์ด๋ฉฐ SSH ํ”„๋กœํ† ์ฝœ๊ณผ ๋น„์Šทํ•œ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, ์ธ์ฆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์—†๋‹ค. ์ €์žฅ์†Œ์— git-export-daemon-ok ํŒŒ์ผ์„ ๋งŒ๋“ค๋ฉด Git ํ”„๋กœํ† ์ฝœ๋กœ ์„œ๋น„์Šคํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ณด์•ˆ์€ ์—†๋‹ค. ์ด ํŒŒ์ผ์ด ์—†๋Š” ์ €์žฅ์†Œ๋Š” Git ํ”„๋กœํ† ์ฝœ๋กœ ์„œ๋น„์Šคํ•  ์ˆ˜ ์—†๋‹ค. ์ด ์ €์žฅ์†Œ๋Š” ๋ˆ„๊ตฌ๋‚˜ Cloneํ•  ์ˆ˜ ์žˆ๊ฑฐ๋‚˜ ์•„๋ฌด๋„ Cloneํ•  ์ˆ˜ ์—†๊ฑฐ๋‚˜ ๋‘˜ ์ค‘์˜ ํ•˜๋‚˜๋งŒ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด ํ”„๋กœํ† ์ฝœ๋กœ๋Š” Push๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์—†๋‹ค. ์—„๋ฐ€ํžˆ ๋งํ•ด์„œ Pushํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ธ์ฆํ•˜๋„๋ก ํ•  ์ˆ˜ ์—†๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๋‹น์‹ ์ด Pushํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์ด ํ”„๋กœ์ ํŠธ์˜ URL์„ ์•„๋Š” ์‚ฌ๋žŒ์€ ๋ˆ„๊ตฌ๋‚˜ Pushํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ƒฅ ์ด๋Ÿฐ ๊ฒƒ๋„ ์žˆ์ง€๋งŒ ์ž˜ ์•ˆ ์“ด๋‹ค๊ณ  ์•Œ๊ณ  ์žˆ์œผ๋ฉด ๋œ๋‹ค.

์žฅ์ 

Git ํ”„๋กœํ† ์ฝœ์€ ์ „์†ก์†๋„๊ฐ€ ๊ฐ€์žฅ ๋น ๋ฅด๋‹ค. ์ „์†ก๋Ÿ‰์ด ๋งŽ์€ ๊ณต๊ฐœ ํ”„๋กœ์ ํŠธ๋‚˜ ๋ณ„๋„์˜ ์ธ์ฆ์ด ํ•„์š” ์—†๊ณ  ์ฝ๊ธฐ๋งŒ ํ—ˆ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์„œ๋น„์Šคํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค. ์•”ํ˜ธํ™”์™€ ์ธ์ฆ์„ ๋นผ๋ฉด SSH ํ”„๋กœํ† ์ฝœ๊ณผ ์ „์†ก ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ๋ณ„๋ฐ˜ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค.

๋‹จ์ 

Git ํ”„๋กœํ† ์ฝœ์€ ์ธ์ฆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์—†๋Š”๊ฒŒ ๋‹จ์ ์ด๋‹ค. Git ํ”„๋กœํ† ์ฝœ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋Š” ๋ฐ”๋žŒ์งํ•˜์ง€ ๋ชปํ•˜๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ SSH ํ”„๋กœํ† ์ฝœ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค. ์†Œ์ˆ˜์˜ ๊ฐœ๋ฐœ์ž๋งŒ Pushํ•  ์ˆ˜ ์žˆ๊ณ  ๋Œ€๋‹ค์ˆ˜ ์‚ฌ๋žŒ์€ git://์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ์„ ์ˆ˜๋งŒ ์žˆ๊ฒŒ ํ•œ๋‹ค. ์–ด์ฉŒ๋ฉด ๊ฐ€์žฅ ์„ค์น˜ํ•˜๊ธฐ ์–ด๋ ค์šด ๋ฐฉ๋ฒ•์ผ ์ˆ˜๋„ ์žˆ๋‹ค. ๋ณ„๋„์˜ ๋ฐ๋ชฌ์ด ํ•„์š”ํ•˜๊ณ  ํ”„๋กœ์ ํŠธ์— ๋งž๊ฒŒ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค. ์ด ์žฅ์˜ Gitosis ์ ˆ์—์„œ ์„ค์ •ํ•˜๋Š” ๋ฒ•์„ ์‚ดํŽด๋ณผ ๊ฒƒ์ด๋‹ค. ์ž์›์„ ์•„๋‚„ ์ˆ˜ ์žˆ๋„๋ก xinetd ๊ฐ™์€ ๊ฒƒ๋„ ์„ค์ •ํ•ด์•ผ ํ•˜๊ณ  ๋ฐฉํ™”๋ฒฝ์„ ํ†ต๊ณผํ•  ์ˆ˜ ์žˆ๋„๋ก 9418 ํฌํŠธ๋„ ์—ด์–ด์•ผ ํ•œ๋‹ค. ์ด ํฌํŠธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํšŒ์‚ฌ๋“ค์ด ํ—ˆ์šฉํ•˜๋Š” ํ‘œ์ค€ ํฌํŠธ๊ฐ€ ์•„๋‹ˆ๋‹ค. ๊ทœ๋ชจ๊ฐ€ ํฐ ํšŒ์‚ฌ๋ผ๋ฉด ๋‹น์—ฐํžˆ ๋ฐฉํ™”๋ฒฝ์—์„œ ์ด ํฌํŠธ๋ฅผ ๋ง‰์•„ ๋†“๋Š”๋‹ค.

HTTP/S ํ”„๋กœํ† ์ฝœ

๋งˆ์ง€๋ง‰์œผ๋กœ, HTTP ํ”„๋กœํ† ์ฝœ์ด ์žˆ๋‹ค. HTTP์™€ HTTPS ํ”„๋กœํ† ์ฝœ์˜ ๋ฏธํ•™์€ ์„ค์ •์ด ๊ฐ„๋‹จํ•˜๋‹ค๋Š” ์ ์ด๋‹ค. HTTP ๋„ํ๋จผํŠธ ๋ฃจํŠธ ๋ฐ‘์— Bare ์ €์žฅ์†Œ๋ฅผ ๋‘๊ณ  post-update ํ›…์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•ด์•ผ ํ•˜๋Š” ์ผ์˜ ์ „๋ถ€๋‹ค(_7์žฅ_์—์„œ Git ํ›…์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋‹ค๋ฃฐ ๊ฒƒ์ด๋‹ค). ์ €์žฅ์†Œ๊ฐ€ ์žˆ๋Š” ์›น ์„œ๋ฒ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ทธ ์ €์žฅ์†Œ๋ฅผ Cloneํ•  ์ˆ˜๋„ ์žˆ๋‹ค. HTTP๋ฅผ ํ†ตํ•ด์„œ ์ €์žฅ์†Œ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ•œ๋‹ค:

$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update

post-update ํ›…์€ Git์— ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉฐ git update-server-info๋ผ๋Š” ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค. ์ด ๋ช…๋ น์–ด๋Š” HTTP๋กœ Fetch์™€ Clone ๋ช…๋ น์ด ์ž˜ ๋™์ž‘ํ•˜๊ฒŒ ํ•œ๋‹ค. SSH๋ฅผ ํ†ตํ•ด์„œ ์ €์žฅ์†Œ์— Pushํ•  ๋•Œ ์‹คํ–‰๋˜๋ฉฐ, ์‚ฌ๋žŒ๋“ค์€ ์•„๋ž˜์™€ ๊ฐ™์ด Cloneํ•œ๋‹ค:

$ git clone http://example.com/gitproject.git

์—ฌ๊ธฐ์„œ๋Š” Apache ์„œ๋ฒ„๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” /var/www/htdocs์„ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ์›น ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค. ๋‹จ์ˆœํžˆ Bare ์ €์žฅ์†Œ๋ฅผ HTTP ๋ฌธ์„œ ๋ฃจํŠธ์— ๋„ฃ์œผ๋ฉด ๋œ๋‹ค. Git ๋ฐ์ดํ„ฐ๋Š” ์ผ๋ฐ˜์ ์ธ ์ •์  ํŒŒ์ผ์ฒ˜๋Ÿผ ์ทจ๊ธ‰๋œ๋‹ค(_9์žฅ_์—์„œ ์ •ํ™•ํžˆ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€ ๋‹ค๋ฃฐ ๊ฒƒ์ด๋‹ค).

HTTP๋ฅผ ํ†ตํ•ด์„œ Pushํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋‹จ์ง€ ์ด ๋ฐฉ๋ฒ•์€ ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” WebDAV ํ™˜๊ฒฝ์„ ์™„๋ฒฝํ•˜๊ฒŒ ๊ตฌ์ถ•ํ•ด์•ผ ํ•œ๋‹ค. ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ฑ…์—์„œ๋„ ๋‹ค๋ฃจ์ง€ ์•Š๋Š”๋‹ค. HTTP ํ”„๋กœํ† ์ฝœ๋กœ Pushํ•˜๊ณ  ์‹ถ์œผ๋ฉด http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt ์„ ์ฝ๊ณ  ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค. HTTP๋ฅผ ํ†ตํ•ด์„œ Pushํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ์ข‹์€ ์ ์€ WebDAV ์„œ๋ฒ„๋ฅผ ์•„๋ฌด๊ฑฐ๋‚˜ ๊ณจ๋ผ ์“ธ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ WebDAV๋ฅผ ์ง€์›ํ•˜๋Š” ์›น ํ˜ธ์ŠคํŒ… ์—…์ฒด๋ฅผ ์ด์šฉํ•˜๋ฉด ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์žฅ์ 

HTTP ํ”„๋กœํ† ์ฝœ์€ ์„ค์ •ํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ๊ฒƒ์ด ์žฅ์ ์ด๋‹ค. ๋ช‡ ๊ฐœ์˜ ํ•„์ˆ˜ ๋ช…๋ น์–ด๋งŒ ์‹คํ–‰ํ•˜๋ฉด ์„ธ๊ณ„ ์–ด๋””์—์„œ๋‚˜ ๋‹น์‹ ์˜ ์ €์žฅ์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋Š”๋ฐ ๋ช‡ ๋ถ„์ด๋ฉด ์ถฉ๋ถ„ํ•˜๋‹ค. HTTP ํ”„๋กœํ† ์ฝœ์€ ์„œ๋ฒ„์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŽ์ด ์žก์•„๋จน์ง€๋„ ์•Š๋Š”๋‹ค. ๋ณดํ†ต์€ ์ •์  HTTP ์„œ๋ฒ„๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ”ํ•œ Apache ์„œ๋ฒ„๋กœ ์ดˆ๋‹น ์ˆ˜์ฒœ ๊ฐœ์˜ ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž‘์€ ์„œ๋ฒ„๋กœ๋„ ์ถฉ๋ถ„ํžˆ ๊ฐ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ HTTPS๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„œ๋น„์Šคํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ „์†กํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ช…๋œ SSL ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋”๋ผ๋„ SSH ๊ณต๊ฐœํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๋ณด๋‹ค ์‰ฝ๋‹ค. ์„œ๋ช…ํ•œ SSL ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋‚˜์„ ๋•Œ๋„ ์žˆ๊ณ  ๋‹จ์ˆœํžˆ HTTPS์œ„์—์„œ HTTP๊ธฐ๋ฐ˜ ์ธ์ฆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋‚˜์„ ๋•Œ๋„ ์žˆ๋‹ค.

HTTP๋Š” ๋งค์šฐ ๋ณดํŽธ์ ์ธ ํ”„๋กœํ† ์ฝœ์ด๋ผ์„œ ๊ฑฐ์˜ ๋ชจ๋“  ํšŒ์‚ฌ๊ฐ€ ํŠธ๋ž˜ํ”ฝ์ด ๋ฐฉํ™”๋ฒฝ์„ ํ†ต๊ณผํ•˜๋„๋ก ํ—ˆ์šฉํ•œ๋‹ค๋Š” ์žฅ์ ๋„ ์žˆ๋‹ค.

๋‹จ์ 

ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” HTTP๊ฐ€ ์ข€ ๋น„ํšจ์œจ์ ์ด๋‹ค. ์ €์žฅ์†Œ์—์„œ Fetchํ•˜๊ฑฐ๋‚˜ Cloneํ•  ๋•Œ ์ข€ ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค. ๋‹ค๋ฅธ ํ”„๋กœํ† ์ฝœ์˜ ๋„คํŠธ์›Œํฌ ์˜ค๋ฒ„ํ—ค๋“œ๋ณด๋‹ค HTTP์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ข€ ๋” ํฌ๋‹ค. ์ง€๋Šฅ์ ์œผ๋กœ ์ •๋ง ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์ „์†กํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— HTTP ํ”„๋กœํ† ์ฝœ์€ ๋ฉ์ฒญํ•œ ํ”„๋กœํ† ์ฝœ(Dumb Protocol)์ด๋ผ๊ณ ๋„ ๋ถ€๋ฅธ๋‹ค. ํšจ์œจ์ ์œผ๋กœ ์ „์†กํ•˜๊ณ ์ž ์„œ๋ฒ„๋Š” ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. HTTP์™€ ๋‹ค๋ฅธ ํ”„๋กœํ† ์ฝœ์˜ ์„ฑ๋Šฅ ์ฐจ์ด๋Š” _9์žฅ_์—์„œ ์ž์„ธํžˆ ์„ค๋ช…ํ•œ๋‹ค.

์„œ๋ฒ„์— Git ์„ค์น˜ํ•˜๊ธฐ

์–ด๋–ค ์„œ๋ฒ„๋ฅผ ์„ค์น˜ํ•˜๋”๋ผ๋„ ์ผ๋‹จ ์ €์žฅ์†Œ๋ฅผ Bare ์ €์žฅ์†Œ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, Bare ์ €์žฅ์†Œ๋Š” ์›Œํ‚น ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์—†๋Š” ์ €์žฅ์†Œ์ด๋‹ค. --bare ์˜ต์…˜์„ ์ฃผ๊ณ  Cloneํ•˜๋ฉด ์ƒˆ๋กœ์šด Bare ์ €์žฅ์†Œ๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค. Bare ์ €์žฅ์†Œ ๋””๋ ‰ํ† ๋ฆฌ๋Š” ๊ด€๋ก€์— ๋”ฐ๋ผ. git ํ™•์žฅ์ž๋กœ ๋๋‚œ๋‹ค:

$ git clone --bare my_project my_project.git
Cloning into bare repository 'my_project.git'...
done.

์ด ๋ช…๋ น์ด ์ถœ๋ ฅํ•˜๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ์กฐ๊ธˆ ์ด์ƒํ•ด๋ณด์ผ ์ˆ˜๋„ ์žˆ๋‹ค. ์‚ฌ์‹ค git clone ๋ช…๋ น์€ git init์„ ํ•˜๊ณ  ๋‚˜์„œ git fetch๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋นˆ ๋””๋ ‰ํ† ๋ฆฌ๋ฐ–์— ๋งŒ๋“ค์ง€ ์•Š๋Š” git init ๋ช…๋ น์˜ ๋ฉ”์‹œ์ง€๋งŒ ๋ณด์—ฌ์ค€๋‹ค. ๊ฐœ์ฒด ์ „์†ก์— ๊ด€๋ จ๋œ ๋ฉ”์‹œ์ง€๋Š” ์•„๋ฌด๊ฒƒ๋„ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ์ „์†ก ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ์ง€ ์•Š์ง€๋งŒ my_project.git ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋ณด๋ฉด Git ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด ์žˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ์‹คํ–‰ํ•œ ๊ฒƒ๊ณผ ๋น„์Šทํ•˜๋‹ค:

$ cp -Rf my_project/.git my_project.git

๋ฌผ๋ก  ์„ค์ • ์ƒ์˜ ๋ฏธ์„ธํ•œ ์ฐจ์ด๊ฐ€ ์žˆ์ง€๋งŒ, ์ €์žฅ์†Œ์˜ ๋‚ด์šฉ๋งŒ ๊ณ ๋ คํ•œ๋‹ค๋ฉด ๊ฐ™๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์›Œํ‚น ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์—†๋Š” Git ์ €์žฅ์†Œ์ธ ๋ฐ๋‹ค๊ฐ€ ๋ณ„๋„์˜ ๋””๋ ‰ํ† ๋ฆฌ๋„ ํ•˜๋‚˜ ๋งŒ๋“ค์—ˆ๋‹ค๋Š” ์ ์—์„œ๋Š” ๊ฐ™๋‹ค.

์„œ๋ฒ„์— Bare ์ €์žฅ์†Œ ๋„ฃ๊ธฐ

Bare ์ €์žฅ์†Œ๋Š” ์ด์ œ ๋งŒ๋“ค์—ˆ์œผ๋‹ˆ๊นŒ ์„œ๋ฒ„์— ๋„ฃ๊ณ  ํ”„๋กœํ† ์ฝœ์„ ์„ค์ •ํ•œ๋‹ค. git.example.com๋ผ๋Š” ์ด๋ฆ„์˜ ์„œ๋ฒ„๋ฅผ ํ•˜๋‚˜ ์ค€๋น„ํ•˜์ž. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์„œ๋ฒ„์— SSH๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ  /opt/git์— Git ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด Bare ์ €์žฅ์†Œ๋ฅผ ๋ณต์‚ฌํ•œ๋‹ค:

$ scp -r my_project.git user@git.example.com:/opt/git

์ด์ œ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋“ค์€ SSH๋กœ ์„œ๋ฒ„์— ์ ‘๊ทผํ•ด์„œ ์ €์žฅ์†Œ๋ฅผ Cloneํ•  ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” /opt/git ๋””๋ ‰ํ† ๋ฆฌ์— ์ฝ๊ธฐ ๊ถŒํ•œ์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค:

$ git clone user@git.example.com:/opt/git/my_project.git

์ด ์„œ๋ฒ„์— SSH๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ /opt/git/my_project.git ๋””๋ ‰ํ† ๋ฆฌ์— ์“ฐ๊ธฐ ๊ถŒํ•œ๊นŒ์ง€ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด ๋ฐ”๋กœ Pushํ•  ์ˆ˜ ์žˆ๋‹ค. git init ๋ช…๋ น์— --shared ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜๋ฉด Git์€ ์ž๋™์œผ๋กœ ๊ทธ๋ฃน ์“ฐ๊ธฐ ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•œ๋‹ค:

$ ssh user@git.example.com
$ cd /opt/git/my_project.git
$ git init --bare --shared

Git ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์‰ฌ์šด์ง€ ์‚ดํŽด๋ณด์•˜๋‹ค. Bare ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค์–ด SSH๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„์— ์˜ฌ๋ฆฌ๋ฉด ๋™๋ฃŒ์™€ ํ•จ๊ป˜ ์ผํ•  ์ค€๋น„๊ฐ€ ๋๋‚œ๋‹ค.

๊ทธ๋Ÿฌ๋‹ˆ๊นŒ Git ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š”๋ฐ ์‚ฌ๋žŒ์ด ํ•  ์ผ์€ ์ •๋ง ๋ณ„๋กœ ์—†๋‹ค. SSH๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„œ๋ฒ„์— ๊ณ„์ •์„ ๋งŒ๋“ค๊ณ  Bare ์ €์žฅ์†Œ๋ฅผ ์‚ฌ๋žŒ๋“ค์ด ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ณณ์— ๋„ฃ์–ด ๋‘๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ๋‹ค๋ฅธ ๊ฒƒ์€ ์•„๋ฌด๊ฒƒ๋„ ํ•„์š” ์—†๋‹ค.

๋‹ค์Œ ์ ˆ์—์„œ๋Š” ์ข€ ๋” ์ •๊ตํ•˜๊ฒŒ ์„ค์ •ํ•˜๋Š” ๋ฒ•์„ ์‚ดํŽด๋ณธ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ณ„์ •์„ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ๋ฒ•, ์ €์žฅ์†Œ๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋ฒ•, Web UI๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฒ•, Gitosis๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ•, ๋“ฑ๋“ฑ์€ ์—ฌ๊ธฐ์—์„œ ์„ค๋ช…ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ผญ ๊ธฐ์–ตํ•ด์•ผ ํ•  ๊ฒƒ์€ ๋™๋ฃŒ์™€ ํ•จ๊ป˜ ๊ฐœ๋ฐœํ•  ๋•Œ ๊ผญ ํ•„์š”ํ•œ ๊ฒƒ์ด SSH ์„œ๋ฒ„์™€ Bare ์ €์žฅ์†Œ๋ฟ์ด๋ผ๋Š” ๊ฒƒ์ด๋‹ค.

๋ฐ”๋กœ ์„ค์ •ํ•˜๊ธฐ

๋งŒ์•ฝ ์ฐฝ์—…์„ ์ค€๋น„ํ•˜๊ณ  ์žˆ๊ฑฐ๋‚˜ ํšŒ์‚ฌ์—์„œ Git์„ ๋ง‰ ๋„์ž…ํ•˜๋ ค๊ณ  ํ•  ๋•Œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๊ฐœ๋ฐœ์ž์˜ ์ˆ˜๊ฐ€ ๋งŽ์ง€ ์•Š์„ ๋•Œ์—๋Š” ์„ค์ •ํ•  ๊ฒŒ ๋ณ„๋กœ ์—†๋‹ค. Git ์„œ๋ฒ„ ์„ค์ •์—์„œ ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ๊ณจ์น˜ ์•„ํ”„๋‹ค. ์‚ฌ๋žŒ์ด ๋งŽ์œผ๋ฉด ์–ด๋–ค ์‚ฌ์šฉ์ž๋Š” ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ณ  ์–ด๋–ค ์‚ฌ์šฉ์ž๋Š” ์ฝ๊ณ  ์“ฐ๊ธฐ ๋‘˜ ๋‹ค ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ์ข€ ๊นŒ๋‹ค๋กญ๋‹ค.

SSH ์ ‘๊ทผ

๋งŒ์•ฝ ๋ชจ๋“  ๊ฐœ๋ฐœ์ž๊ฐ€ SSH๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„๊ฐ€ ์žˆ์œผ๋ฉด ๋„ˆ๋ฌด ์‰ฝ๊ฒŒ ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์•ž์„œ ๋งํ–ˆ๋“ฏ์ด ํ•  ์ผ์ด ๋ณ„๋กœ ์—†๋‹ค. ์ €์žฅ์†Œ์˜ ๊ถŒํ•œ์„ ๊ผผ๊ผผํ•˜๊ฒŒ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋ฉด ๊ทธ๋ƒฅ ์šด์˜์ฒด์ œ์˜ ํŒŒ์ผ์‹œ์Šคํ…œ ๊ถŒํ•œ๊ด€๋ฆฌ๋ฅผ ์ด์šฉํ•œ๋‹ค. ๋™๋ฃŒ๊ฐ€ ์ €์žฅ์†Œ์— ์“ฐ๊ธฐ ์ ‘๊ทผ์„ ํ•ด์•ผ ํ•˜๋Š” ๋ฐ ์•„์ง SSH๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„๊ฐ€ ์—†์œผ๋ฉด ํ•˜๋‚˜ ๋งˆ๋ จํ•ด์•ผ ํ•œ๋‹ค. ์•„๋งˆ ๋…์ž์—๊ฒŒ ์„œ๋ฒ„๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ ์„œ๋ฒ„์—๋Š” ์ด๋ฏธ SSH ์„œ๋ฒ„๊ฐ€ ์„ค์น˜๋ผ ์žˆ์–ด์„œ ์ด๋ฏธ SSH๋กœ ์ ‘์†ํ•˜๊ณ  ์žˆ์„ ๊ฒƒ์ด๋‹ค.

๋™๋ฃŒ๊ฐ€ ์ ‘์†ํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ช‡ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. ์ฒซ์งธ๋กœ ๋ชจ๋‘์—๊ฒŒ ๊ณ„์ •์„ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์ด ์ œ์ผ ๋‹จ์ˆœํ•˜์ง€๋งŒ ๋‹ค์†Œ ๊ท€์ฐฎ์€ ๋ฐฉ๋ฒ•์ด๋‹ค. ํŒ€์›๋งˆ๋‹ค adduser๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ  ์ž„์‹œ ์•”ํ˜ธ๋ฅผ ๋ถ€์—ฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํ†ต ์ด ๋ฐฉ๋ฒ•์„ ์“ฐ๊ณ  ์‹ถ์–ด ํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋‘˜์งธ๋กœ ์„œ๋ฒ„๋งˆ๋‹ค git์ด๋ผ๋Š” ๊ณ„์ •์„ ํ•˜๋‚˜์”ฉ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ํ•„์š”ํ•œ ์‚ฌ์šฉ์ž์˜ SSH ๊ณต๊ฐœํ‚ค๋ฅผ ๋ชจ๋‘ ๋ชจ์•„์„œ git ๊ณ„์ •์˜ ~/.ssh/authorized_keysํŒŒ์ผ์— ๋ชจ๋“  ํ‚ค๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ชจ๋‘ git ๊ณ„์ •์œผ๋กœ ๊ทธ ์„œ๋ฒ„์— ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด git ๊ณ„์ •์€ ์ปค๋ฐ‹ ๋ฐ์ดํ„ฐ์—๋Š” ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ๋‹ค์‹œ ๋งํ•ด์„œ ์ ‘์†ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ SSH ๊ณ„์ •๊ณผ ์ปค๋ฐ‹์— ์ €์žฅ๋˜๋Š” ์‚ฌ์šฉ์ž๋Š” ์•„๋ฌด ์ƒ๊ด€์—†๋‹ค.

์ด๋ฏธ LDAP ์„œ๋ฒ„ ๊ฐ™์€ ์ค‘์•™์ง‘์ค‘์‹ ์ธ์ฆ ์†Œ์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด SSH ์„œ๋ฒ„๊ฐ€ ํ•ด๋‹น ์ธ์ฆ์„ ์ด์šฉํ•˜๋„๋ก ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. SSH ์ธ์ฆ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์ค‘ ์•„๋ฌด๊ฑฐ๋‚˜ ํ•˜๋‚˜ ์ด์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ๊ทธ ์„œ๋ฒ„์— ์ ‘์†์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

SSH ๊ณต๊ฐœํ‚ค ๋งŒ๋“ค๊ธฐ

์ด๋ฏธ ๋งํ–ˆ๋“ฏ์ด ๋งŽ์€ Git ์„œ๋ฒ„๋“ค์€ SSH ๊ณต๊ฐœํ‚ค๋กœ ์ธ์ฆํ•œ๋‹ค. ๊ณต๊ฐœํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ผ๋‹จ ๊ณต๊ฐœํ‚ค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ๊ณต๊ฐœํ‚ค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ๋ชจ๋“  ์šด์˜์ฒด์ œ๊ฐ€ ๋น„์Šทํ•˜๋‹ค. ๋จผ์ € ํ‚ค๊ฐ€ ์žˆ๋Š”์ง€๋ถ€ํ„ฐ ํ™•์ธํ•˜์ž. ์‚ฌ์šฉ์ž์˜ SSH ํ‚ค๋“ค์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ์ž์˜ ~/.ssh ๋””๋ ‰ํ† ๋ฆฌ์— ์ €์žฅํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ๋งŒ์•ฝ ๋””๋ ‰ํ† ๋ฆฌ์˜ ํŒŒ์ผ์„ ์‚ดํŽด๋ณด๋ฉด ๊ณต๊ฐœํ‚ค๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค:

$ cd ~/.ssh
$ ls
authorized_keys2  id_dsa       known_hosts
config            id_dsa.pub

something, something.pub์ด๋ผ๋Š” ํ˜•์‹์œผ๋กœ ๋œ ํŒŒ์ผ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. something์€ ๋ณดํ†ต id_dsa๋‚˜ id_rsa๋ผ๊ณ  ๋ผ ์žˆ๋‹ค. ๊ทธ์ค‘ .pubํŒŒ์ผ์ด ๊ณต๊ฐœํ‚ค์ด๊ณ  ๋‹ค๋ฅธ ํŒŒ์ผ์€ ๊ฐœ์ธํ‚ค์ด๋‹ค. ๋งŒ์•ฝ ์ด ํŒŒ์ผ์ด ์—†๊ฑฐ๋‚˜ .ssh ๋””๋ ‰ํ† ๋ฆฌ๋„ ์—†์œผ๋ฉด ssh-keygen์ด๋ผ๋Š” ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ํ‚ค๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค. ssh-keygen ํ”„๋กœ๊ทธ๋žจ์€ ๋ฆฌ๋ˆ…์Šค๋‚˜ Mac์˜ SSH ํŒจํ‚ค์ง€์— ํฌํ•จ๋ผ ์žˆ๊ณ  ์œˆ๋„๋Š” MSysGit ํŒจํ‚ค์ง€ ์•ˆ์— ๋“ค์–ด ์žˆ๋‹ค:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/schacon/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/schacon/.ssh/id_rsa.
Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub.
The key fingerprint is:
43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local

๋จผ์ € ํ‚ค๋ฅผ ์–ด๋””์— ์ €์žฅํ• ์ง€ ๊ฒฝ๋กœ๋ฅผ(.ssh/id_rsa) ์ž…๋ ฅํ•˜๊ณ  ์•”ํ˜ธ๋ฅผ ๋‘ ๋ฒˆ ์ž…๋ ฅํ•œ๋‹ค. ์ด๋•Œ ์•”ํ˜ธ๋ฅผ ๋น„์›Œ๋‘๋ฉด ํ‚ค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์•”ํ˜ธ๋ฅผ ๋ฌป์ง€ ์•Š๋Š”๋‹ค.

์‚ฌ์šฉ์ž๋Š” ๊ทธ ๋‹ค์Œ์— ์ž์‹ ์˜ ๊ณต๊ฐœ๊ธฐ๋ฅผ Git ์„œ๋ฒ„ ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค. ์‚ฌ์šฉ์ž๋Š” .pub ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•˜์—ฌ ๋ฉ”์ผ์„ ๋ณด๋‚ด๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ๊ณต๊ฐœํ‚ค๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ๊ฒผ๋‹ค:

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== schacon@agadorlaptop.local

๋‹ค์–‘ํ•œ ์šด์˜ ์ฒด์ œ์—์„œ SSH ํ‚ค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ด ๊ถ๊ธˆํ•˜๋ฉด http://github.com/guides/providing-your-ssh-key์— ์žˆ๋Š” Github ์„ค๋ช…์„œ๋ฅผ ์ฐพ์•„๋ณด๋Š” ๊ฒŒ ์ข‹๋‹ค.

์„œ๋ฒ„์— ์„ค์ •ํ•˜๊ธฐ

์„œ๋ฒ„์— ์„ค์ •ํ•˜๋Š” ์ผ์„ ์‚ดํŽด๋ณด์ž. ์ผ๋‹จ Ubuntu๊ฐ™์€ ํ‘œ์ค€ ๋ฆฌ๋ˆ…์Šค ๋ฐฐํฌํŒ์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์•„๋งˆ๋„ authorized_keys ํŒŒ์ผ๋กœ ์ธ์ฆํ•  ๊ฒƒ์ด๋‹ค. ๋จผ์ € git ๊ณ„์ •์„ ๋งŒ๋“ค๊ณ  ์‚ฌ์šฉ์ž ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ์— .ssh ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ ๋‹ค:

$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh

authorized_keys ํŒŒ์ผ์— SSH ๊ณต๊ฐœํ‚ค๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „์— ์ด๋ฏธ ์ด๋ฉ”์ผ๋กœ ๊ณต๊ฐœํ‚ค๋ฅผ ๋ช‡ ๊ฐœ ๋ฐ›์•„์„œ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ๊ณต๊ฐœํ‚ค๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€ ๋‹ค์‹œ ํ•œ๋ฒˆ ํ™•์ธํ•œ๋‹ค:

$ cat /tmp/id_rsa.john.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L
ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k
Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez
Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv
O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq
dAv8JggJICUvax2T9va5 gsg-keypair

authorized_keys ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•œ๋‹ค:

$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys
$ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys

--bare ์˜ต์…˜์„ ์ฃผ๊ณ  git init์„ ์‹คํ–‰ํ•ด์„œ ์›Œํ‚น ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์—†๋Š” ๋นˆ ์ €์žฅ์†Œ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ ๋‹ค:

$ cd /opt/git
$ mkdir project.git
$ cd project.git
$ git --bare init

์ด์ œ John์”จ, Josie์”จ, Jessica์”จ๋Š” ์ด ์ €์žฅ์†Œ๋ฅผ ๋ฆฌ๋ชจํŠธ ์ €์žฅ์†Œ๋กœ ๋“ฑ๋กํ•˜๋ฉด ๋ธŒ๋žœ์น˜๋ฅผ Pushํ•  ์ˆ˜ ์žˆ๋‹ค. ํ”„๋กœ์ ํŠธ๋งˆ๋‹ค ์ ์–ด๋„ ํ•œ ๋ช…์€ ์„œ๋ฒ„์— ์ ‘์†ํ•˜์—ฌ Bare ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. git ๊ณ„์ •๊ณผ ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“  ์„œ๋ฒ„์˜ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ด gitserver๋ผ๊ณ  ํ•˜์ž. ๋งŒ์•ฝ ์ด ์„œ๋ฒ„๊ฐ€ ๋‚ด๋ถ€๋ง์— ์žˆ์œผ๋ฉด gitserver๊ฐ€ ๊ทธ ์„œ๋ฒ„๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก DNS์— ์„ค์ •ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ช…๋ น์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค:

# on Johns computer
$ cd myproject
$ git init
$ git add .
$ git commit -m 'initial commit'
$ git remote add origin git@gitserver:/opt/git/project.git
$ git push origin master

์ด์ œ ์ด ํ”„๋กœ์ ํŠธ๋ฅผ Cloneํ•˜๊ณ  ๋‚˜์„œ ์ˆ˜์ •ํ•˜๊ณ  Pushํ•œ๋‹ค:

$ git clone git@gitserver:/opt/git/project.git
$ cd project
$ vim README
$ git commit -am 'fix for the README file'
$ git push origin master

๊ฐœ๋ฐœ์ž๋“ค์ด ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋Š” Git ์„œ๋ฒ„๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  git-shell์ด๋ผ๋Š” ๊ฑธ ์‚ฌ์šฉํ•ด์„œ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ์‰˜๋กœ git ๊ณ„์ •์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๋“ค์ด Git ๋ง๊ณ  ๋‹ค๋ฅธ ๊ฒƒ์„ ํ•  ์ˆ˜ ์—†๋„๋ก ์ œํ•œํ•˜๋Š” ๊ฒƒ์ด๋‹ค. git ๊ณ„์ •์˜ ๋กœ๊ทธ์ธ ์‰˜์„ ์ด๊ฒƒ์œผ๋กœ ์„ค์ •ํ•˜๋ฉด git ์‚ฌ์šฉ์ž๋Š” ์ผ๋ฐ˜์ ์ธ ์‰˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ํ†ต์ƒ์˜ bash, csh ๋Œ€์‹ ์— git-shell์„ ๋กœ๊ทธ์ธ ์‰˜๋กœ ์„ค์ •ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ์ด๊ฒƒ์„ ํ•˜๋ ค๋ฉด /etc/passwd ํŒŒ์ผ์„ ํŽธ์ง‘ํ•œ๋‹ค:

$ sudo vim /etc/passwd

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์€ ์ค„์„ ์ฐพ๋Š”๋‹ค:

git:x:1000:1000::/home/git:/bin/sh

/bin/sh๋ฅผ /usr/bin/git-shell๋กœ(which git-shell ๋ช…๋ น์œผ๋กœ ์–ด๋””์— ์„ค์น˜๋๋Š”์ง€ ํ™•์ธํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค) ๋ณ€๊ฒฝํ•œ๋‹ค:

git:x:1000:1000::/home/git:/usr/bin/git-shell

์ด์ œ git ๊ณ„์ •์€ Git ์ €์žฅ์†Œ์— Pushํ•˜๊ณ  Pullํ•˜๋Š” ๊ฒƒ๋งŒ ๊ฐ€๋Šฅํ•˜๊ณ  ์„œ๋ฒ„์˜ ์‰˜์—๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. ์‹ค์ œ๋กœ ๋กœ๊ทธ์ธ์„ ํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋กœ ๋กœ๊ทธ์ธ์ด ๊ฑฐ์ ˆ๋œ๋‹ค:

$ ssh git@gitserver
fatal: What do you think I am? A shell?
Connection to gitserver closed.

๊ณต๊ฐœํ•˜๊ธฐ

์ต๋ช…์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ฝ๊ธฐ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ? ํ”„๋กœ์ ํŠธ๋ฅผ ๋น„๊ณต๊ฐœ๊ฐ€ ์•„๋‹ˆ๋ผ ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ๋กœ ๊ณต๊ฐœํ•œ๋‹ค๊ฑฐ๋‚˜ ์ž๋™ ๋นŒ๋“œ ์„œ๋ฒ„๋‚˜ CI(Continuous Integration) ์„œ๋ฒ„๊ฐ€ ๋งŽ์•„์„œ ๊ณ„์ •๋งˆ๋‹ค ํ•˜๋‚˜ํ•˜๋‚˜ ์„ค์ •ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋‹ˆ๋ฉด ๊ทธ๋ƒฅ ๋งค๋ฒˆ SSH ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒŒ ๊ท€์ฐฎ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๊ทธ๋ƒฅ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ต๋ช…์˜ ์‚ฌ์šฉ์ž๋„ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ?

๋ถ„๋ช… ์›น ์„œ๋ฒ„๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด๋‹ค. ์ด ์žฅ์˜ ์ฒซ ๋ถ€๋ถ„์— ์„ค๋ช…ํ–ˆ๋“ฏ์ด ์›น ์„œ๋ฒ„๋ฅผ ์„ค์น˜ํ•˜๊ณ  Git ์ €์žฅ์†Œ๋ฅผ ๋ฌธ์„œ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์— ๋‘๊ณ  post-update ํ›…์„ ์ผœ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ๋จผ์ € ์„ค๋ช…ํ–ˆ๋˜ ์˜ˆ์ œ๋ฅผ ๋”ฐ๋ผ ํ•ด๋ณด์ž. /opt/git ๋””๋ ‰ํ† ๋ฆฌ์— ์ €์žฅ์†Œ๊ฐ€ ์žˆ๊ณ  ์„œ๋ฒ„์— Apache๊ฐ€ ์„ค์น˜๋ผ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ์•„๋ฌด ์›น ์„œ๋ฒ„๋‚˜ ๋‹ค ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด ์˜ˆ์ œ์—์„œ๋Š” Apache๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ด๋ฏ€๋กœ ์•„์ฃผ ๊ธฐ๋ณธ์ ์ธ Apache ์„ค์ •๋งŒ์„ ๋ณด์—ฌ์ค„ ๊ฒƒ์ด๋‹ค.

๋จผ์ € ์ด ํ›…์„ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค:

$ cd project.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update

post-update ํ›…์€ ๋ฌด์Šจ ์ผ์„ ํ• ๊นŒ? ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:

$ cat .git/hooks/post-update
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".
#

exec git-update-server-info

SSH๋ฅผ ํ†ตํ•ด์„œ ์„œ๋ฒ„์— Pushํ•˜๋ฉด Git์€ ์ด ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ HTTP๋ฅผ ํ†ตํ•ด์„œ๋„ Fetchํ•  ์ˆ˜ ์žˆ๋„๋ก ํŒŒ์ผ๋ฅผ ๊ฐฑ์‹ ํ•œ๋‹ค.

๊ทธ๋‹ค์Œ Apache ์„ค์ •์— VirtualHost ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด ํ•ญ๋ชฉ์—์„œ ๋ฌธ์„œ ๋ฃจํŠธ๊ฐ€ Git ์ €์žฅ์†Œ์˜ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ๋˜๋„๋ก ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  *.gitserver๋กœ ์ ‘์†ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ๋ชจ๋‘ ์ด ์„œ๋ฒ„์— ์ ‘์†ํ•˜๋„๋ก ํ•œ๋‹ค. ์™€์ผ๋“œ์นด๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ VirtualHostํ•ญ๋ชฉ์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•œ๋‹ค:

<VirtualHost *:80>
    ServerName git.gitserver
    DocumentRoot /opt/git
    <Directory /opt/git/>
        Order allow, deny
        allow from all
    </Directory>
</VirtualHost>

๊ทธ๋ฆฌ๊ณ  Apache ์„œ๋ฒ„๋Š” www-data ๊ถŒํ•œ์œผ๋กœ CGI ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์— /opt/git ๋””๋ ‰ํ† ๋ฆฌ์˜ ๊ทธ๋ฃน ์†Œ์œ  ๊ถŒํ•œ์„ www-data๋กœ ์ˆ˜์ •ํ•ด ์ฃผ์–ด์•ผ ์›น ์„œ๋ฒ„๋กœ ์ ‘๊ทผํ•˜๋Š” ์‚ฌ์šฉ์ž๋“ค์ด ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.

$ chgrp -R www-data /opt/git

Apache๋ฅผ ์žฌ์‹œ์ž‘ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ URL๋กœ ์ €์žฅ์†Œ๋ฅผ Cloneํ•  ์ˆ˜ ์žˆ๋‹ค:

$ git clone http://git.gitserver/project.git

์ด๋ ‡๊ฒŒ ์‚ฌ์šฉ์ž๋“ค์ด HTTP๋กœ ํ”„๋กœ์ ํŠธ์— ์ ‘๊ทผํ•˜๋„๋ก ์„ค์ •ํ•˜๋Š” ๋ฐ ๋ช‡ ๋ถ„๋ฐ–์— ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  Git ๋ฐ๋ชฌ์œผ๋กœ๋„ ๋˜‘๊ฐ™์ด ์ธ์ฆ ์—†์ด ์ ‘์†ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ฐ๋ชฌ์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์ง€๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด๊ฒƒ์€ ๋‹ค์Œ ์ ˆ์—์„œ ์‚ดํŽด๋ณผ ๊ฒƒ์ด๋‹ค.

GitWeb

ํ”„๋กœ์ ํŠธ ์ €์žฅ์†Œ๋ฅผ ๋‹จ์ˆœํžˆ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์„ค์ •์€ ๋‹ค๋ค˜๋‹ค. ์ด์ œ๋Š” ์›น ๊ธฐ๋ฐ˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์„ค์ •ํ•ด๋ณด์ž. Git์—๋Š” GitWeb์ด๋ผ๋Š” CGI ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ œ๊ณตํ•ด์„œ ์‰ฝ๊ฒŒ ์›น์—์„œ ์ €์žฅ์†Œ๋ฅผ ์กฐํšŒํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค. http://git.kernel.org๊ฐ™์€ ์‚ฌ์ดํŠธ์—์„œ GitWeb์„ ๊ตฌ๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค(๊ทธ๋ฆผ 4-1).

Git์€ GitWeb์„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ์„œ๋ฒ„๋ฅผ ์ž ์‹œ ๋„์šฐ๋Š” ๋ช…๋ น์„ ์ œ๊ณตํ•œ๋‹ค. ์‹œ์Šคํ…œ์— lighttpd๋‚˜ webrick ๊ฐ™์€ ๊ฒฝ๋Ÿ‰ ์›น์„œ๋ฒ„๊ฐ€ ์„ค์น˜๋ผ ์žˆ์–ด์•ผ ์ด ๋ช…๋ น์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฆฌ๋ˆ…์Šค์—์„œ๋Š” lighttpd๊ฐ€ ์„ค์น˜๋ผ ์žˆ์„ ํ™•๋ฅ ์ด ๋†’๊ณ  ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๊ทธ๋ƒฅ git instaweb์„ ์‹คํ–‰ํ•˜๋ฉด ๋ฐ”๋กœ ์‹คํ–‰๋œ๋‹ค. Mac์˜ Leopard ๋ฒ„์ „์€ Ruby๊ฐ€ ๋ฏธ๋ฆฌ ์„ค์น˜๋ผ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— webrick์ด ๋” ๋‚ซ๋‹ค. lighttpd์ด ์•„๋‹ˆ๋ผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด --httpd ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค:

$ git instaweb --httpd=webrick
[2009-02-21 10:02:21] INFO  WEBrick 1.3.1
[2009-02-21 10:02:21] INFO  ruby 1.8.6 (2008-03-03) [universal-darwin9.0]

1234 ํฌํŠธ๋กœ HTTPD ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•˜๊ณ  ์ด ํŽ˜์ด์ง€๋ฅผ ์—ฌ๋Š” ์›น๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ž๋™์œผ๋กœ ์‹คํ–‰์‹œํ‚จ๋‹ค. ๊ฝค ํŽธ๋ฆฌํ•˜๋‹ค. ํ•„์š”ํ•œ ์ผ์„ ๋ชจ๋‘ ๋งˆ์น˜๊ณ  ๋‚˜์„œ ๊ฐ™์€ ๋ช…๋ น์–ด์— --stop ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ์ค‘์ง€ํ•œ๋‹ค:

$ git instaweb --httpd=webrick --stop

ํ•ญ์ƒ ์ ‘์†๊ฐ€๋Šฅํ•œ ์›น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์šด์˜ํ•˜๋ ค๋ฉด ๋จผ์ € ์›น์„œ๋ฒ„์— ์ด CGI ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•œ๋‹ค. apt๋‚˜ yum์œผ๋กœ๋„ gitweb์„ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์—ฌ๊ธฐ์—์„œ๋Š” ์ˆ˜๋™์œผ๋กœ ์„ค์น˜ํ•œ๋‹ค. ๋จผ์ € GitWeb์ด ํฌํ•จ๋œ Git ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๊ตฌํ•œ ๋‹ค์Œ CGI ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋นŒ๋“œํ•œ๋‹ค:

$ git clone git://git.kernel.org/pub/scm/git/git.git
$ cd git/
$ make GITWEB_PROJECTROOT="/opt/git" \
        prefix=/usr gitweb/gitweb.cgi
$ sudo cp -Rf gitweb /var/www/

๋นŒ๋“œํ•  ๋•Œ GITWEB_PROJECTROOT ๋ณ€์ˆ˜๋กœ Git ์ €์žฅ์†Œ์˜ ์œ„์น˜๋ฅผ ์•Œ๋ ค์ค˜์•ผ ํ•œ๋‹ค. ์ด์ œ Apache๊ฐ€ ์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก VirtualHost ํ•ญ๋ชฉ์„ ์„ค์ •ํ•œ๋‹ค:

<VirtualHost *:80>
    ServerName gitserver
    DocumentRoot /var/www/gitweb
    <Directory /var/www/gitweb>
        Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch
        AllowOverride All
        order allow,deny
        Allow from all
        AddHandler cgi-script cgi
        DirectoryIndex gitweb.cgi
    </Directory>
</VirtualHost>

๋‹ค์‹œ ๋งํ•ด์„œ GitWeb์€ CGI๋ฅผ ์ง€์›ํ•˜๋Š” ์›น์„œ๋ฒ„๋ผ๋ฉด ์•„๋ฌด๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด์ œ http://gitserver/์— ์ ‘์†ํ•˜์—ฌ ์˜จ๋ผ์ธ์œผ๋กœ ์ €์žฅ์†Œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ http://git.gitserver๋ฅผ ํ†ตํ•ด์„œ HTTP ํ”„๋กœํ† ์ฝœ๋กœ ์ €์žฅ์†Œ๋ฅผ Cloneํ•˜๊ณ  Fetchํ•  ์ˆ˜ ์žˆ๋‹ค.

Gitosis

์ฒ˜์Œ์—๋Š” ๋ชจ๋“  ์‚ฌ์šฉ์ž์˜ ๊ณต๊ฐœํ‚ค๋ฅผ authorized_keys์— ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋„ ๋ถˆํŽธํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ, ์‚ฌ์šฉ์ž๊ฐ€ ์ˆ˜๋ฐฑ ๋ช…์ด ๋„˜์œผ๋ฉด ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ๊ณ ํ†ต์Šค๋Ÿฝ๋‹ค. ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ๋งค๋ฒˆ ์„œ๋ฒ„์— ์ ‘์†ํ•  ์ˆ˜๋„ ์—†๊ณ  ๊ถŒํ•œ ๊ด€๋ฆฌ๋„ ์•ˆ๋œ๋‹ค. authorized_keys์— ๋“ฑ๋ก๋œ ๋ชจ๋“  ์‚ฌ์šฉ์ž๋Š” ๋ˆ„๊ตฌ๋‚˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ๋งค์šฐ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” Gitosis๋ผ๋Š” ์†Œํ”„ํŠธ์›จ์–ด๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. Gitosis๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ authorized_keys ํŒŒ์ผ์„ ๊ด€๋ฆฌํ•˜๊ณ  ์ ‘๊ทผ์ œ์–ด๋ฅผ ๋•๋Š” ์Šคํฌ๋ฆฝํŠธ ํŒจํ‚ค์ง€๋‹ค. ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ๊ถŒํ•œ์„ ๊ด€๋ฆฌํ•˜๋Š” UI๊ฐ€ ์›น ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ์ผ์ข…์˜ Git ์ €์žฅ์†Œ๋ผ๋Š” ์ ์ด ์žฌ๋ฏธ์žˆ๋‹ค. ํ”„๋กœ์ ํŠธ ์„ค์ •์„ Pushํ•˜๋ฉด ๊ทธ ์„ค์ •์ด Gitosis์— ์ ์šฉ๋œ๋‹ค. ์‹ ๋น„๋กญ๋‹ค!

Gitosis๋ฅผ ์„ค์น˜ํ•˜๊ธฐ๊ฐ€ ์‰ฝ์ง€๋Š” ์•Š์ง€๋งŒ ๊ทธ๋ ‡๋‹ค๊ณ  ์–ด๋ ต์ง€๋„ ์•Š๋‹ค. Gitosis๋Š” ๋ฆฌ๋ˆ…์Šค์— ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์‰ฝ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” Ubuntu 8.10 ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

Gitosis๋Š” Python์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋จผ์ € Python setuptools ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•œ๋‹ค. Ubuntu์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์น˜ํ•œ๋‹ค:

$ apt-get install python-setuptools

๊ทธ๋ฆฌ๊ณ  Gitosis ํ”„๋กœ์ ํŠธ ์‚ฌ์ดํŠธ์—์„œ Gitosis๋ฅผ Cloneํ•œ ํ›„ ์„ค์น˜ํ•œ๋‹ค:

$ git clone https://github.com/tv42/gitosis.git
$ cd gitosis
$ sudo python setup.py install

Gitosis๊ฐ€ ์„ค์น˜๋˜๋ฉด Gitosis๋Š” ์ €์žฅ์†Œ ๋””๋ ‰ํ† ๋ฆฌ๋กœ /home/git๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ์ด๋Œ€๋กœ ์‚ฌ์šฉํ•ด๋„ ๊ดœ์ฐฎ์ง€๋งŒ, ์šฐ๋ฆฌ์˜ ์ €์žฅ์†Œ๋Š” ์ด๋ฏธ /opt/git์— ์žˆ๋‹ค. ๋‹ค์‹œ ์„ค์ •ํ•˜์ง€ ๋ง๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๋งŒ๋“ค์ž:

$ ln -s /opt/git /home/git/repositories

Gitosis๊ฐ€ ํ‚ค๋“ค์„ ๊ด€๋ฆฌํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ ํŒŒ์ผ์€ ์‚ญ์ œํ•˜๊ณ  ๋‹ค์‹œ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ์ด์ œ๋ถ€ํ„ฐ๋Š” Gitosis๊ฐ€ authorized_keysํŒŒ์ผ์„ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•  ๊ฒƒ์ด๋‹ค. authorized_keys ํŒŒ์ผ์„ ๋ฐฑ์—…ํ•ด๋‘์ž:

$ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak

๊ทธ๋ฆฌ๊ณ  git ๊ณ„์ •์˜ ์‰˜์„ git-shell๋กœ ๋ณ€๊ฒฝํ–ˆ์—ˆ๋‹ค๋ฉด ์›๋ž˜๋Œ€๋กœ ๋ณต์›ํ•ด์•ผ ํ•œ๋‹ค. Gitosis๊ฐ€ ๋Œ€์‹  ์ด ์ผ์„ ๋งก์•„์ค„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์›ํ•ด๋„ ์‚ฌ๋žŒ๋“ค์€ ์—ฌ์ „ํžˆ ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์—†๋‹ค. /etc/passwd ํŒŒ์ผ์˜ ๋‹ค์Œ ์ค„์„:

git:x:1000:1000::/home/git:/usr/bin/git-shell

์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ€๊ฒฝํ•œ๋‹ค:

git:x:1000:1000::/home/git:/bin/sh

์ด์ œ Gitosis๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ์ฐจ๋ก€๋‹ค. gitosis-init ๋ช…๋ น์„ ๊ณต๊ฐœํ‚ค์™€ ํ•จ๊ป˜ ์‹คํ–‰ํ•œ๋‹ค. ๋งŒ์•ฝ ๊ณต๊ฐœํ‚ค๊ฐ€ ์„œ๋ฒ„์— ์—†์œผ๋ฉด ๊ณต๊ฐœํ‚ค๋ฅผ ์„œ๋ฒ„๋กœ ๋ณต์‚ฌํ•ด์™€์•ผ ํ•œ๋‹ค:

$ sudo -H -u git gitosis-init < /tmp/id_dsa.pub
Initialized empty Git repository in /opt/git/gitosis-admin.git/
Reinitialized existing Git repository in /opt/git/gitosis-admin.git/

์ด ๋ช…๋ น์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ํ‚ค์˜ ์‚ฌ์šฉ์ž๋Š” Gitosis๋ฅผ ์ œ์–ดํ•˜๋Š” ํŒŒ์ผ๋“ค์ด ์žˆ๋Š” Gitosis ์„ค์ • ์ €์žฅ์†Œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ˆ˜๋™์œผ๋กœ post-update ์Šคํฌ๋ฆฝํŠธ์— ์‹คํ–‰๊ถŒํ•œ์„ ๋ถ€์—ฌํ•œ๋‹ค:

$ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update

๋ชจ๋“  ์ค€๋น„๊ฐ€ ๋๋‚ฌ๋‹ค. ์„ค์ •์ด ์ž˜ ๋์œผ๋ฉด ์ถ”๊ฐ€ํ•œ ๊ณต๊ฐœํ‚ค์˜ ์‚ฌ์šฉ์ž๋กœ SSH ์„œ๋ฒ„์— ์ ‘์†ํ–ˆ์„ ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๊ฒŒ ๋œ๋‹ค:

$ ssh git@gitserver
PTY allocation request failed on channel 0
ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.
fatal: unrecognized command 'gitosis-serve schacon@quaternion'
  Connection to gitserver closed.

์ด๊ฒƒ์€ ์ ‘์†์„ ์‹œ๋„ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ์‹๋ณ„ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, Git ๋ช…๋ น์ด ์•„๋‹ˆ์–ด์„œ ๊ฑฐ์ ˆํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์‹ค์ œ Git ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰์‹œ์ผœ๋ณด์ž. Gitosis ์ œ์–ด ์ €์žฅ์†Œ๋ฅผ Cloneํ•œ๋‹ค:

# on your local computer
$ git clone git@gitserver:gitosis-admin.git

gitosis-admin์ด๋ผ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์ƒ๊ธด๋‹ค. ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์šฉ์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค:

$ cd gitosis-admin
$ find .
./gitosis.conf
./keydir
./keydir/scott.pub

gitoiss.conf ํŒŒ์ผ์€ ์‚ฌ์šฉ์ž, ์ €์žฅ์†Œ, ๊ถŒํ•œ ๋“ฑ์„ ๋ช…์‹œํ•˜๋Š” ์„ค์ •ํŒŒ์ผ์ด๋‹ค. keydir ๋””๋ ‰ํ† ๋ฆฌ์—๋Š” ์ €์žฅ์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž์˜ ๊ณต๊ฐœํ‚ค๊ฐ€ ์ €์žฅ๋œ๋‹ค. ์‚ฌ์šฉ์ž๋งˆ๋‹ค ๊ณต๊ฐœํ‚ค๊ฐ€ ํ•˜๋‚˜์”ฉ ์žˆ๊ณ  ์ด ๊ณต๊ฐœํ‚ค๋กœ ์„œ๋ฒ„์— ์ ‘๊ทผํ•œ๋‹ค. ์ด ์˜ˆ์ œ์—์„œ๋Š” scott.pub์ด์ง€๋งŒ keydir ์•ˆ์— ์žˆ๋Š” ํŒŒ์ผ์˜ ์ด๋ฆ„์€ ์‚ฌ์šฉ์ž๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค. ํŒŒ์ผ ์ด๋ฆ„์€ gitosis-init ์Šคํฌ๋ฆฝํŠธ๋กœ ๊ณต๊ฐœํ‚ค๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ๊ฒฐ์ •๋˜๋Š”๋ฐ ๊ณต๊ฐœํ‚ค ๋ ๋ถ€๋ถ„์— ์žˆ๋Š” ์ด๋ฆ„์ด ์‚ฌ์šฉ๋œ๋‹ค.

์ด์ œ gitosis.conf ํŒŒ์ผ์„ ์—ด์–ด๋ณด์ž. ์ง€๊ธˆ ๋ง‰ Cloneํ•œ gitosis-admin ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ์ •๋ณด๋งŒ ๋“ค์–ด ์žˆ๋‹ค:

$ cat gitosis.conf
[gitosis]

[group gitosis-admin]
members = scott
writable = gitosis-admin

scott์ด๋ผ๋Š” ์‚ฌ์šฉ์ž๋Š” Gitosis๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ ์‚ฌ์šฉํ•œ ๊ณต๊ฐœํ‚ค์˜ ์‚ฌ์šฉ์ž์ด๋‹ค. ์ด ์‚ฌ์šฉ์ž๋งŒ gitosis-admin ํ”„๋กœ์ ํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•ด๋ณด์ž. mobile ๋‹จ๋ฝ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๊ทธ ํ”„๋กœ์ ํŠธ์— ์†ํ•œ ๊ฐœ๋ฐœ์ž๋‚˜ ํ”„๋กœ์ ํŠธ์— ์ ‘๊ทผํ•ด์•ผ ํ•˜๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ํ˜„์žฌ๋Š” scott์ด์™ธ์— ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๊ฐ€ ์—†์œผ๋‹ˆ scott๋งŒ ์ถ”๊ฐ€ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  iphone_project ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค:

[group mobile]
writable = iphone_project
members = scott

gitosis-admin ํ”„๋กœ์ ํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ์ปค๋ฐ‹ํ•˜๊ณ  ์„œ๋ฒ„์— Pushํ•ด์•ผ ์ˆ˜์ •ํ•œ ์„ค์ •์ด ์ ์šฉ๋œ๋‹ค:

$ git commit -am 'add iphone_project and mobile group'
[master 8962da8] add iphone_project and mobile group
 1 file changed, 4 insertions(+)
$ git push origin master
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 272 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@gitserver:gitosis-admin.git
   fb27aec..8962da8  master -> master

๋กœ์ปฌ์— ์žˆ๋Š” iphone_project ํ”„๋กœ์ ํŠธ์— ์ด ์„œ๋ฒ„๋ฅผ ๋ฆฌ๋ชจํŠธ ์ €์žฅ์†Œ๋กœ ์ถ”๊ฐ€ํ•˜๊ณ  Pushํ•˜๋ฉด ์„œ๋ฒ„์— ์ƒˆ๋กœ์šด ์ €์žฅ์†Œ๊ฐ€ ์ถ”๊ฐ€๋œ๋‹ค. ์„œ๋ฒ„์— ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค ๋•Œ ์ด์ œ๋Š” ์ˆ˜๋™์œผ๋กœ Bare ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋‹ค. ์ฒ˜์Œ Pushํ•  ๋•Œ Gitosis๊ฐ€ ์•Œ์•„์„œ ์ƒ์„ฑํ•ด ์ค€๋‹ค:

$ git remote add origin git@gitserver:iphone_project.git
$ git push origin master
Initialized empty Git repository in /opt/git/iphone_project.git/
Counting objects: 3, done.

Writing objects: 100% (3/3), 230 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To git@gitserver:iphone_project.git * [new branch] master -> master

Gitosis๋ฅผ ์ด์šฉํ•  ๋•Œ์—๋Š” ์ €์žฅ์†Œ ๊ฒฝ๋กœ๋ฅผ ๋ช…์‹œํ•  ํ•„์š”๋„ ์—†๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์—†๋‹ค. ๋‹จ์ง€ ์ฝœ๋ก  ๋’ค์— ํ”„๋กœ์ ํŠธ ์ด๋ฆ„๋งŒ ์ ์–ด๋„ Gitosis๊ฐ€ ์•Œ์•„์„œ ์ฐพ์•„ ์ค€๋‹ค.

๋™๋ฃŒ์™€ ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๊ณต์œ ํ•˜๋ ค๋ฉด ๋™๋ฃŒ์˜ ๊ณต๊ฐœํ‚ค๋„ ๋ชจ๋‘ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ~/.ssh/authorized_keys ํŒŒ์ผ์— ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ keydir ๋””๋ ‰ํ† ๋ฆฌ์— ํ•˜๋‚˜์˜ ๊ณต๊ฐœํ‚ค๋ฅผ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด ๊ณต๊ฐœํ‚ค์˜ ํŒŒ์ผ์ด๋ฆ„์ด gitosis.conf ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ๊ฒฐ์ •ํ•œ๋‹ค. John, Josie, Jessica์˜ ๊ณต๊ฐœํ‚ค๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด์ž:

$ cp /tmp/id_rsa.john.pub keydir/john.pub
$ cp /tmp/id_rsa.josie.pub keydir/josie.pub
$ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub

์ด ์„ธ ์‚ฌ๋žŒ์„ ๋ชจ๋‘ mobile ํŒ€์œผ๋กœ ์ถ”๊ฐ€ํ•˜์—ฌ iphone_project ์— ๋Œ€ํ•œ ์ฝ๊ธฐ, ์“ฐ๊ธฐ๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค:

[group mobile]
members = scott john josie jessica
writable = iphone_project

์ด ํŒŒ์ผ์„ ์ปค๋ฐ‹ํ•˜๊ณ  Pushํ•˜๊ณ  ๋‚˜๋ฉด ๋„ค ๋ช… ๋ชจ๋‘ iphone_project๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

Gitosis์˜ ์ ‘๊ทผ์ œ์–ด ๋ฐฉ๋ฒ•์€ ๋งค์šฐ ๋‹จ์ˆœํ•˜๋‹ค. ๋งŒ์•ฝ ์ด ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด์„œ John์€ ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค์ •ํ•˜๋ ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ•œ๋‹ค:

[group mobile]
members = scott josie jessica
writable = iphone_project

[group mobile_ro]
members = john
readonly = iphone_project

์ด์ œ John์€ ํ”„๋กœ์ ํŠธ๋ฅผ Cloneํ•˜๊ฑฐ๋‚˜ Fetchํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ํ”„๋กœ์ ํŠธ์— Pushํ•  ์ˆ˜๋Š” ์—†๋‹ค. ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ž์™€ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์–ด๋„ ํ•„์š”ํ•œ ๋งŒํผ ๊ทธ๋ฃน์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  members ํ•ญ๋ชฉ์— ์‚ฌ์šฉ์ž ๋Œ€์‹  ๊ทธ๋ฃน๋ช…์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๊ทธ๋ฃน๋ช… ์•ž์— @๋ฅผ ๋ถ™์ด๋ฉด ๊ทธ ๊ทธ๋ฃน์˜ ์‚ฌ์šฉ์ž๋ฅผ ๊ทธ๋Œ€๋กœ ์ƒ์†ํ•œ๋‹ค:

[group mobile_committers]
members = scott josie jessica

[group mobile]
members   = @mobile_committers
writable  = iphone_project

[group mobile_2]
members   = @mobile_committers john
writable  = another_iphone_project

[gitosis] ์ ˆ์— loglevel=DEBUG๋ผ๊ณ  ์ ์œผ๋ฉด ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ๋„์›€์ด ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์„ค์ •์ด ๊ผฌ์—ฌ๋ฒ„๋ ค์„œ Pushํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜๋ฉด ์„œ๋ฒ„์— ์žˆ๋Š” ํŒŒ์ผ์„ ์ˆ˜๋™์œผ๋กœ ๊ณ ์ณ๋„ ๋œ๋‹ค. Gitosis๋Š” /home/git/.gitosis.conf ํŒŒ์ผ์˜ ์ •๋ณด๋ฅผ ์ฝ๊ธฐ ๋•Œ๋ฌธ์— ์ด ํŒŒ์ผ์„ ๊ณ ์นœ๋‹ค. gitosis.conf๋Š” Pushํ•  ๋•Œ ๊ทธ ์œ„์น˜๋กœ ๋ณต์‚ฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜๋™์œผ๋กœ ๊ณ ์นœ ํŒŒ์ผ์€ gitosis-admin ํ”„๋กœ์ ํŠธ๊ฐ€ ๋‹ค์Œ์— Push๋  ๋•Œ๊นŒ์ง€ ์œ ์ง€๋œ๋‹ค.

Gitolite

์ด ์ ˆ์—์„œ๋Š” Gitolite๊ฐ€ ๋ญ๊ณ  ๊ธฐ๋ณธ์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์„ค์น˜ํ•˜๋Š” ์ง€๋ฅผ ์‚ดํŽด๋ณธ๋‹ค. ๋ฌผ๋ก  Gitolite์— ๋“ค์–ด ์žˆ๋Š” Gitolite ๋ฌธ์„œ๋Š” ์–‘์ด ๋งŽ์•„์„œ ์ด ์ ˆ์—์„œ ๋ชจ๋‘ ๋‹ค๋ฃฐ ์ˆ˜ ์—†๋‹ค. Gitolite๋Š” ๊ณ„์† ์ง„ํ™”ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ฑ…์˜ ๋‚ด์šฉ๊ณผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค. ์ตœ์‹  ๋‚ด์šฉ์€ ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

Gitolite์€ ๊ฐ„๋‹จํžˆ ๋งํ•ด Git ์œ„์—์„œ ์šด์˜ํ•˜๋Š” ๊ถŒํ•œ ์ œ์–ด(Authorization) ๋„๊ตฌ๋‹ค. ์‚ฌ์šฉ์ž ์ธ์ฆ(Authentication)์€ sshd์™€ httpd๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ ‘์†ํ•œ ์ ‘์†ํ•˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ๊ฐ€๋ ค๋‚ด๋Š” ๊ฒƒ์ด ์ธ์ฆ(Authentication)์ด๊ณ  ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ์„ ๊ฐ€๋ ค๋‚ด๋Š” ์ผ์€ ๊ถŒํ•œ ์ œ์–ด(Authorization)์ด๋‹ค.

Gitolite๋Š” ์ €์žฅ์†Œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ €์žฅ์†Œ์˜ ๋ธŒ๋žœ์น˜๋‚˜ ํƒœ๊ทธ์—๋„ ๊ถŒํ•œ์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ์–ด๋–ค ์‚ฌ๋žŒ์€ refs(๋ธŒ๋žœ์น˜๋‚˜ ํƒœ๊ทธ)์— Pushํ•  ์ˆ˜ ์žˆ๊ณ  ์–ด๋–ค ์‚ฌ๋žŒ์€ ํ•  ์ˆ˜ ์—†๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์„ค์น˜ํ•˜๊ธฐ

๋ณ„๋„ ๋ฌธ์„œ๋ฅผ ์ฝ์ง€ ์•Š์•„๋„ ์œ ๋‹‰์Šค ๊ณ„์ •๋งŒ ํ•˜๋‚˜ ์žˆ์œผ๋ฉด Gitolite๋ฅผ ์‰ฝ๊ฒŒ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ธ€์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฆฌ๋ˆ…์Šค๋“ค๊ณผ ์†”๋ผ๋ฆฌ์Šค 10์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ๋งˆ์ณค๋‹ค. Git, Perl, OpenSSH๊ฐ€ ํ˜ธํ™˜๋˜๋Š” SSH ์„œ๋ฒ„๊ฐ€ ์„ค์น˜๋ผ ์žˆ์œผ๋ฉด root ๊ถŒํ•œ๋„ ํ•„์š” ์—†๋‹ค. ์•ž์„œ ์‚ฌ์šฉํ–ˆ๋˜ gitserver๋ผ๋Š” ์„œ๋ฒ„์™€ ๊ทธ ์„œ๋ฒ„์— git ๊ณ„์ •์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•œ๋‹ค.

Gitolite๋Š” ๋ณดํ†ต์˜ ์„œ๋ฒ„ ์†Œํ”„ํŠธ์›จ์–ด์™€๋Š” ๋‹ฌ๋ฆฌ SSH๋ฅผ ํ†ตํ•ด์„œ ์ ‘๊ทผํ•œ๋‹ค. ์„œ๋ฒ„์˜ ๋ชจ๋“  ๊ณ„์ •์€ ๊ทผ๋ณธ์ ์œผ๋กœ "Gitolite ํ˜ธ์ŠคํŠธ"๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด ์ฑ…์—์„œ๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์„ค์น˜ ๋ฐฉ๋ฒ•์œผ๋กœ ์„ค๋ช…ํ•œ๋‹ค. ์ž์„ธํ•œ ์„ค๋ช… ๋ฌธ์„œ๋Š” Gitolite์˜ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•œ๋‹ค.

๋จผ์ € ์„œ๋ฒ„์— git ๊ณ„์ •์„ ๋งŒ๋“ค๊ณ  git ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ ํ•œ๋‹ค. ์‚ฌ์šฉ์ž์˜ SSH ๊ณต๊ฐœํ‚ค(ssh-keygen์œผ๋กœ ์ƒ์„ฑํ•œ SSH ๊ณต๊ฐœํ‚ค๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ~/.ssh/id_rsa.pub์— ์œ„์น˜ํ•จ)๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ <์ด๋ฆ„>.pub ํŒŒ์ผ๋กœ ์ €์žฅํ•œ๋‹ค(์ด ์ฑ…์˜ ์˜ˆ์ œ์—์„œ๋Š” scott.pub๋กœ ์ €์žฅ). ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช…๋ น์„ ์‹คํ–‰ํ•œ๋‹ค:

$ git clone git://github.com/sitaramc/gitolite
$ gitolite/install -ln
    # $HOME/bin๊ฐ€ ์ด๋ฏธ $PATH์— ๋“ฑ๋ก๋ผ์žˆ๋‹ค๊ณ  ๊ฐ€์ •
$ gitolite setup -pk $HOME/scott.pub

๋งˆ์ง€๋ง‰ ๋ช…๋ น์€ gitolite-admin๋ผ๋Š” ์ƒˆ Git ์ €์žฅ์†Œ๋ฅผ ์„œ๋ฒ„์— ๋งŒ๋“ ๋‹ค.

๋‹ค์‹œ ์ž‘์—…ํ•˜๋˜ ํ™˜๊ฒฝ์œผ๋กœ ๋Œ์•„๊ฐ€์„œ git clone git@gitserver:gitolite-admin ๋ช…๋ น์œผ๋กœ ์„œ๋ฒ„์˜ ์ €์žฅ์†Œ๋ฅผ Clone ํ–ˆ์„ ๋–„ ๋ฌธ์ œ์—†์ด Clone ๋˜๋ฉด Gitolite๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์„ค์น˜๋œ ๊ฒƒ์ด๋‹ค. ์ด gitolite-admin ์ €์žฅ์†Œ์˜ ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•˜๊ณ  Pushํ•˜์—ฌ Gitolite์„ ์„ค์น˜๋ฅผ ๋งˆ์น˜๋„๋ก ํ•œ๋‹ค.

์ž์‹ ์—๊ฒŒ ๋งž๊ฒŒ ์„ค์น˜ํ•˜๊ธฐ

๋ณดํ†ต์€ ๊ธฐ๋ณธ์„ค์ •์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜์ง€๋งŒ, ์ž์‹ ์—๊ฒŒ ๋งž๊ฒŒ ๊ณ ์ณ์„œ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ผ๋ถ€ ์„ค์ •์€ ์ฃผ์„์ด ์ž˜ ๋‹ฌ๋ ค์žˆ๋Š” rc ํŒŒ์ผ์„ ๊ฐ„๋‹จํžˆ ๊ณ ์ณ์„œ ์“ธ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ž์„ธํ•œ ์„ค์ •์„ ์œ„ํ•ด์„œ๋Š” Gitolite๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด๋„๋ก ํ•œ๋‹ค.

์„ค์ • ํŒŒ์ผ๊ณผ ์ ‘๊ทผ์ œ์–ด ๊ทœ์น™

์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ์— Cloneํ•œ gitolite-admin ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ํ•ด์„œ ์–ด๋–ค ๊ฒƒ๋“ค์ด ์žˆ๋Š”์ง€ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์ž:

$ cd ~/gitolite-admin/
$ ls
conf/  keydir/
$ find conf keydir -type f
conf/gitolite.conf
keydir/scott.pub
$ cat conf/gitolite.conf

repo gitolite-admin
    RW+                 = scott

repo testing
    RW+                 = @all

gitolite setup ๋ช…๋ น์„ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ์ฃผ์—ˆ๋˜ ๊ณต๊ฐœํ‚ค ํŒŒ์ผ์˜ ์ด๋ฆ„์ธ scott์€ gitolite-admin ์ €์žฅ์†Œ์— ๋Œ€ํ•œ ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ ๊ถŒํ•œ์„ ๊ฐ–๋„๋ก ๊ณต๊ฐœํ‚ค๊ฐ€ ๋“ฑ๋ก๋ผ ์žˆ๋‹ค.

์‚ฌ์šฉ์ž๋ฅผ ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•˜๊ธฐ๋„ ์‰ฝ๋‹ค. "alice"๋ผ๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์ƒˆ๋กœ ๋“ฑ๋กํ•˜๋ ค๋ฉด ์šฐ์„  ๋“ฑ๋กํ•  ์‚ฌ๋žŒ์˜ ๊ณต๊ฐœํ‚ค ํŒŒ์ผ์„ ์–ป์–ด์„œ alice.pub๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ gitolite-admin ๋””๋ ‰ํ† ๋ฆฌ ์•„๋ž˜์— keydir ๋””๋ ‰ํ† ๋ฆฌ์— ์ €์žฅํ•œ๋‹ค. ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•œ ์ด ํŒŒ์ผ์„ Addํ•˜๊ณ  ์ปค๋ฐ‹ํ•œ ํ›„ Push๋ฅผ ํ•˜๋ฉด alice๋ผ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋“ฑ๋ก๋œ ๊ฒƒ์ด๋‹ค.

Gitolite์˜ ์„ค์ • ํŒŒ์ผ์ธ conf/example.conf์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ Gitolite ๋ฌธ์„œ์— ์„ค๋ช…์ด ์ž˜ ๋˜์–ด ์žˆ๋‹ค. ์ด ์ฑ…์—์„œ๋Š” ์ฃผ์š” ์ผ๋ถ€ ์„ค์ •์— ๋Œ€ํ•ด์„œ๋งŒ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณธ๋‹ค.

์ €์žฅ์†Œ์˜ ์‚ฌ์šฉ์ž ๊ทธ๋ฃน์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ทธ๋ฃน์€ ๋งคํฌ๋กœ์™€ ๋น„์Šทํ•˜๋‹ค. ๊ทธ๋ฃน์„ ๋งŒ๋“ค ๋•Œ๋Š” ๊ทธ ๊ทธ๋ฃน์ด ํ”„๋กœ์ ํŠธ์˜ ๊ทธ๋ฃน์ธ์ง€ ์‚ฌ์šฉ์ž์˜ ๊ทธ๋ฃน์ธ์ง€ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์ง€๋งŒ _์‚ฌ์šฉ_ํ•  ๋•Œ์—๋Š” ๋‹ค๋ฅด๋‹ค.

@oss_repos      = linux perl rakudo git gitolite
@secret_repos   = fenestra pear

@admins         = scott
@interns        = ashok
@engineers      = sitaram dilbert wally alice
@staff          = @admins @engineers @interns

๊ทธ๋ฆฌ๊ณ  ref ๋‹จ์œ„๋กœ ๊ถŒํ•œ์„ ์ œ์–ดํ•œ๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ๋ฅผ ๋ณด์ž. ์ธํ„ด(interns)์€ int ๋ธŒ๋žœ์น˜๋งŒ Pushํ•  ์ˆ˜ ์žˆ๊ณ  engineers๋Š” eng-๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ธŒ๋žœ์น˜์™€ rc ๋’ค์— ์ˆซ์ž๊ฐ€ ๋ถ™๋Š” ํƒœ๊ทธ๋งŒ Pushํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ด€๋ฆฌ์ž๋Š” ๋ชจ๋“  ref์— ๋ฌด์—‡์ด๋“ ์ง€(๋˜๋Œ๋ฆฌ๊ธฐ๋„ ํฌํ•จ๋จ) ํ•  ์ˆ˜ ์žˆ๋‹ค.

repo @oss_repos
    RW  int$                = @interns
    RW  eng-                = @engineers
    RW  refs/tags/rc[0-9]   = @engineers
    RW+                     = @admins

RW๋‚˜ RW+ ๋’ค์— ๋‚˜์˜ค๋Š” ํ‘œํ˜„์‹์€ ์ •๊ทœํ‘œํ˜„์‹(regex)์ด๊ณ  Pushํ•˜๋Š” ref ์ด๋ฆ„์˜ ํŒจํ„ด์„ ์˜๋ฏธํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” refex๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ๋ฌผ๋ก  refex๋Š” ์—ฌ๊ธฐ์— ๋ณด์—ฌ์ค€ ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๊ฐ•๋ ฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ, ํŽ„์˜ ์ •๊ทœํ‘œํ˜„์‹์— ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๋…์ž๋„ ์žˆ์œผ๋‹ˆ ์—ฌ๊ธฐ์„œ๋Š” ๋ฌด๋ฆฌํ•˜์ง€ ์•Š์•˜๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๋ฏธ ์˜ˆ์ƒํ–ˆ๊ฒ ์ง€๋งŒ Gitolite๋Š” refs/heads/๋ผ๊ณ  ์‹œ์ž‘ํ•˜์ง€ ์•Š๋Š” refex์— ๋Œ€ํ•ด์„œ๋Š” ์•”๋ฌต์ ์œผ๋กœ refs/heads/๊ฐ€ ์ƒ๋žต๋œ ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•œ๋‹ค.

ํŠน์ • ์ €์žฅ์†Œ์— ์‚ฌ์šฉํ•˜๋Š” ๊ทœ์น™์„ ํ•œ ๊ณณ์— ๋ชจ์•„ ๋†“์ง€ ์•Š์•„๋„ ๊ดœ์ฐฎ๋‹ค. ์œ„์— ๋ณด์—ฌ์ค€ oss_repos ์ €์žฅ์†Œ ์„ค์ •๊ณผ ๋‹ค๋ฅธ ์ €์žฅ์†Œ ์„ค์ •์ด ๋งˆ๊ตฌ ์„ž์—ฌ ์žˆ์–ด๋„ ๊ดœ์ฐฎ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ชฉ์ ์ด ๋ถ„๋ช…ํ•˜๊ณ  ์ œํ•œ์ ์ธ ๊ทœ์น™์„ ์•„๋ฌด ๋ฐ๋‚˜ ์ถ”๊ฐ€ํ•ด๋„ ์ข‹๋‹ค:

repo gitolite
    RW+                     = sitaram

์ด ๊ทœ์น™์€ gitolite ์ €์žฅ์†Œ๋ฅผ ์œ„ํ•ด ์ง€๊ธˆ ๋ง‰ ์ถ”๊ฐ€ํ•œ ๊ทœ์น™์ด๋‹ค.

์ด์ œ๋Š” ์ ‘๊ทผ์ œ์–ด ๊ทœ์น™์ด ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์ ์šฉ๋˜๋Š”์ง€ ์„ค๋ช…ํ•œ๋‹ค. ์ด์ œ๋ถ€ํ„ฐ ๊ทธ ๋‚ด์šฉ์„ ์‚ดํŽด๋ณด์ž.

Gitolite๋Š” ์ ‘๊ทผ ์ œ์–ด๋ฅผ ๋‘ ๋‹จ๊ณ„๋กœ ํ•œ๋‹ค. ์ฒซ ๋‹จ๊ณ„๊ฐ€ ์ €์žฅ์†Œ ๋‹จ๊ณ„์ธ๋ฐ ์ ‘๊ทผํ•˜๋Š” ์ €์žฅ์†Œ์˜ ref ์ค‘์—์„œ ํ•˜๋‚˜๋ผ๋„ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์œผ๋ฉด ์‹ค์ œ๋กœ ๊ทธ ์ €์žฅ์†Œ ์ „๋ถ€์— ๋Œ€ํ•ด ์ฝ๊ธฐ, ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ๋ธŒ๋žœ์น˜๋‚˜ ํƒœ๊ทธ ๋‹จ์œ„๋กœ ์ œ์–ดํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์˜ค์ง "์“ฐ๊ธฐ" ์ ‘๊ทผ๋งŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. ์–ด๋Š ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ref ์ด๋ฆ„์œผ๋กœ ์ ‘๊ทผ์„ ์‹œ๋„ํ•˜๋ฉด(W๋‚˜ +๊ฐ™์€) ์„ค์ • ํŒŒ์ผ์— ์ •์˜๋œ ์ˆœ์„œ๋Œ€๋กœ ์ ‘๊ทผ ์ œ์–ด ๊ทœ์น™์ด ์ ์šฉ๋œ๋‹ค. ๊ทธ ์ˆœ์„œ๋Œ€๋กœ ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ ref ์ด๋ฆ„์„ ๋น„๊ตํ•˜๋Š”๋ฐ ref ์ด๋ฆ„์˜ ๊ฒฝ์šฐ ๋‹จ์ˆœํžˆ ๋ฌธ์ž์—ด์„ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ •๊ทœ ํ‘œํ˜„์‹์œผ๋กœ ๋น„๊ตํ•œ๋‹ค. ํ•ด๋‹น๋˜๋Š” ๊ฒƒ์„ ์ฐพ์œผ๋ฉด ์ •์ƒ์ ์œผ๋กœ Push๋˜์ง€๋งŒ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด ๊ฑฐ์ ˆ๋œ๋‹ค.

"deny" ๊ทœ์น™์„ ๊ผผ๊ผผํ•˜๊ฒŒ ์ œ์–ดํ•˜๊ธฐ

์ง€๊ธˆ๊นŒ์ง€๋Š” R, RW, RW+ ๊ถŒํ•œ์— ๋Œ€ํ•ด์„œ๋งŒ ๋‹ค๋ค˜๋‹ค. Gitolite๋Š” "deny" ๊ทœ์น™์„ ์œ„ํ•ด์„œ - ๊ถŒํ•œ๋„ ์ง€์›ํ•œ๋‹ค. ์ด๊ฒƒ์œผ๋กœ ๋ณต์žก๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ๋‹ค. -๋กœ ๊ฑฐ์ ˆ๋„ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทœ์น™์˜ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜๋‹ค.

๋‹ค์‹œ ๋งํ•ด์„œ engineers๊ฐ€ master์™€ integ ๋ธŒ๋žœ์น˜ ์ด์™ธ์˜ ๋ชจ๋“  ๋ธŒ๋žœ์น˜๋ฅผ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ  ์‹ถ์œผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ•œ๋‹ค:

    RW  master integ    = @engineers
    -   master integ    = @engineers
    RW+                 = @engineers

์ฆ‰, ์ ‘๊ทผ์ œ์–ด ๊ทœ์น™์„ ์ˆœ์„œ๋Œ€๋กœ ์ฐพ๊ธฐ ๋•Œ๋ฌธ์— ์ˆœ์„œ๋Œ€๋กœ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๊ทœ์น™์€ master๋‚˜ integ ๋ธŒ๋žœ์น˜์— ๋Œ€ํ•ด์„œ ์ฝ๊ธฐ, ์“ฐ๊ธฐ๋งŒ ํ—ˆ์šฉํ•˜๊ณ  ๋˜๋Œ๋ฆฌ๊ธฐ๋Š” ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. master๋‚˜ integ ๋ธŒ๋žœ์น˜๋ฅผ ๋˜๋Œ๋ฆฌ๋Š” Push๋Š” ์ฒซ ๋ฒˆ์งธ ๊ทœ์น™์— ์–ด๊ธ‹๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋กœ ๋‘ ๋ฒˆ์งธ ๊ทœ์น™์œผ๋กœ ๋„˜์–ด๊ฐ„๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฑฐ๊ธฐ์„œ ๊ฑฐ์ ˆ๋œ๋‹ค. master๋‚˜ integ ๋ธŒ๋žœ์น˜ ์ด์™ธ ๋‹ค๋ฅธ ref์— ๋Œ€ํ•œ Push๋Š” ์ฒซ ๋ฒˆ์งธ ๊ทœ์น™๊ณผ ๋‘ ๋ฒˆ์งธ ๊ทœ์น™์—๋Š” ๋งŒ์กฑํ•˜์ง€ ์•Š๊ณ  ๋งˆ์ง€๋ง‰ ๊ทœ์น™์œผ๋กœ ํ—ˆ์šฉ๋œ๋‹ค.

ํŒŒ์ผ ๋‹จ์œ„๋กœ Push๋ฅผ ์ œ์–ดํ•˜๊ธฐ

๋ธŒ๋žœ์น˜ ๋‹จ์œ„๋กœ Push๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ˆ˜์ •๋œ ํŒŒ์ผ ๋‹จ์œ„๋กœ๋„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Makefile์„ ๋ณด์ž. Makefile ํŒŒ์ผ์— ์˜์กดํ•˜๋Š” ํŒŒ์ผ์€ ๋งค์šฐ ๋งŽ๊ณ  ๋ณดํ†ต ๊ผผ๊ผผํ•˜๊ฒŒ ์ˆ˜์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋ฌด๋‚˜ Makefile์„ ์ˆ˜์ •ํ•˜๊ฒŒ ๋‘˜ ์ˆ˜ ์—†๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•œ๋‹ค:

repo foo
    RW                      =   @junior_devs @senior_devs

    -   VREF/NAME/Makefile  =   @junior_devs

์˜ˆ์ „ ๋ฒ„์ „์˜ Gitolite์—์„œ ๋ฒ„์ „์„ ์˜ฌ๋ฆฌ๋ ค๋Š” ์‚ฌ์šฉ์ž๋Š” ์„ค์ •์ด ๋งŽ์ด ๋‹ฌ๋ผ์ง„ ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. Gitolite์˜ ๋ฒ„์ „์—… ๊ฐ€์ด๋“œ๋ฅผ ํ•„ํžˆ ์ฐธ๊ณ ํ•˜์ž.

Personal ๋ธŒ๋žœ์น˜

Gitolite๋Š” ๋˜ "Personal ๋ธŒ๋žœ์น˜"๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ธฐ๋Šฅ์„ ์ง€์›ํ•œ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์‹ค์ œ๋กœ "Personal ๋ธŒ๋žœ์น˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค"๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์ด ๋” ์ ์ ˆํ•˜๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ๊ธฐ์—…์—์„œ ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค.

Git์„ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜๋ ค๊ณ  "Pull ํ•ด์ฃผ์„ธ์š”"๋ผ๊ณ  ๋งํ•ด์•ผ ํ•˜๋Š” ์ผ์ด ์ž์ฃผ ์ƒ๊ธด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ธฐ์—…์—์„œ๋Š” ์ธ์ฆํ•˜์ง€ ์•Š์€ ์ ‘๊ทผ์„ ์ ˆ๋Œ€ ํ—ˆ์šฉํ•˜์ง€๋„ ์•Š๋Š” ๋ฐ๋‹ค๊ฐ€ ์•„์˜ˆ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ์ปดํ“จํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. ๊ทธ๋ž˜์„œ ๊ณต์œ ํ•˜๋ ค๋ฉด ์ค‘์•™ ์„œ๋ฒ„์— Pushํ•˜๊ณ  ๋‚˜์„œ Pullํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ๋งํ•ด์•ผ๋งŒ ํ•œ๋‹ค.

์ค‘์•™์ง‘์ค‘์‹ VCS์—์„œ ์ด๋ ‡๊ฒŒ ๋งˆ๊ตฌ ์‚ฌ์šฉํ•˜๋ฉด ๋ธŒ๋žœ์น˜ ์ด๋ฆ„์ด ์ถฉ๋Œํ•  ํ™•๋ฅ ์ด ๋†’๋‹ค. ๊ทธ๋•Œ๋งˆ๋‹ค ๊ด€๋ฆฌ์ž๋Š” ์ถ”๊ฐ€๋กœ ๊ถŒํ•œ์„ ๊ด€๋ฆฌํ•ด์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ด€๋ฆฌ์ž์˜ ๋…ธ๋ ฅ์ด ์“ธ๋ฐ์—†์ด ๋‚ญ๋น„๋œ๋‹ค.

Gitolite๋Š” ๋ชจ๋“  ๊ฐœ๋ฐœ์ž๊ฐ€ "personal"์ด๋‚˜ "scratch" ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•œ๋‹ค. ์ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” refs/personal/<devname>/* ๋ผ๊ณ  ํ‘œํ˜„ํ•œ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Gitolite ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•œ๋‹ค.

"์™€์ผ๋“œ์นด๋“œ" ์ €์žฅ์†Œ

Gitolite๋Š” ํŽ„ ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ์ €์žฅ์†Œ ์ด๋ฆ„์„ ํ‘œํ˜„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์™€์ผ๋“œ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ assignments/s[0-9][0-9]/a[0-9][0-9] ๊ฐ™์€ ์ •๊ทœํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ƒˆ๋กœ์šด ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๊ถŒํ•œ ๋ชจ๋“œ์ธ C ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ €์žฅ์†Œ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“  ์‚ฌ๋žŒ์—๊ฒŒ๋Š” ์ž๋™์œผ๋กœ ์ ‘๊ทผ ๊ถŒํ•œ์ด ๋ถ€์—ฌ๋œ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์ฃผ๋ ค๋ฉด R ๋˜๋Š” RW ๊ถŒํ•œ์„ ์„ค์ •ํ•œ๋‹ค. ๋‹ค์‹œ ํ•œ๋ฒˆ ๋งํ•˜์ง€๋งŒ ๋ฌธ์„œ์— ๋ชจ๋“  ๋‚ด์šฉ์ด ๋‹ค ์žˆ์œผ๋ฏ€๋กœ ๊ผญ ๋ณด๊ธฐ๋ฅผ ๋ฐ”๋ž€๋‹ค.

๊ทธ ๋ฐ–์˜ ๊ธฐ๋Šฅ๋“ค

๋งˆ์ง€๋ง‰์œผ๋กœ ์•Œ๊ณ  ์žˆ์œผ๋ฉด ์œ ์šฉํ•œ ๊ฒƒ๋“ค์ด ์žˆ๋‹ค. Gitolite์—๋Š” ๋งŽ์€ ๊ธฐ๋Šฅ์ด ์žˆ๊ณ  ์ž์„ธํ•œ ๋‚ด์šฉ์€ "Faq, Tip, ๋“ฑ๋“ฑ"์˜ ๋‹ค๋ฅธ ๋ฌธ์„œ์— ์ž˜ ์„ค๋ช…๋ผ ์žˆ๋‹ค.

๋กœ๊น…: ๋ˆ„๊ตฐ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋ฉด Gitolite๋Š” ๋ฌด์กฐ๊ฑด ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธด๋‹ค. ๊ด€๋ฆฌ์ž๊ฐ€ ํ•œ๋ˆˆํŒŒ๋Š” ์‚ฌ์ด์— ๋˜๋Œ๋ฆฌ๊ธฐ(RW+) ๊ถŒํ•œ์„ ๊ฐ€์ง„ ๋ง๋‚˜๋‹ˆ๊ฐ€ master ๋ธŒ๋žœ์น˜๋ฅผ ๋‚ ๋ ค๋ฒ„๋ฆด ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๋กœ๊ทธ ํŒŒ์ผ์ด ๊ตฌ์›ํ•ด์ค€๋‹ค. ์ด ๋กœ๊ทธ ํŒŒ์ผ์„ ์ฐธ๊ณ ํ•˜์—ฌ ๋ฒ„๋ ค์ง„ SHA๋ฅผ ๋น ๋ฅด๊ณ  ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

์ ‘๊ทผ ๊ถŒํ•œ ๋ณด์—ฌ์ฃผ๊ธฐ: ๋งŒ์•ฝ ์–ด๋–ค ์„œ๋ฒ„์—์„œ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๋ ค๊ณ  ํ•  ๋•Œ ํ•„์š”ํ•œ ๊ฒƒ์ด ๋ฌด์—‡์ผ๊นŒ? Gitolite๋Š” ํ•ด๋‹น ์„œ๋ฒ„์— ๋Œ€ํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ €์žฅ์†Œ๊ฐ€ ๋ฌด์—‡์ธ์ง€, ์–ด๋–ค ๊ถŒํ•œ์„ ๊ฐ€์กŒ๋Š”์ง€ ๋ณด์—ฌ์ค€๋‹ค:

    hello scott, this is git@git running gitolite3 v3.01-18-g9609868 on git 1.7.4.4

         R     anu-wsd
         R     entrans
         R  W  git-notes
         R  W  gitolite
         R  W  gitolite-admin
         R     indic_web_input
         R     shreelipi_converter

๊ถŒํ•œ ์œ„์ž„: ์กฐ์ง ๊ทœ๋ชจ๊ฐ€ ํฌ๋ฉด ์ €์žฅ์†Œ์— ๋Œ€ํ•œ ์ฑ…์ž„์„ ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ๋‚˜๋ˆ  ๊ฐ€์ง€๋Š” ๊ฒŒ ์ข‹๋‹ค. ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ๊ฐ์ž ๋งก์€ ๋ฐ”๋ฅผ ๊ด€๋ฆฌํ•˜๋„๋ก ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์ฃผ์š” ๊ด€๋ฆฌ์ž์˜ ์—…๋ฌด๊ฐ€ ์ค„์–ด๋“ค๊ธฐ์— ๋ณ‘๋ชฉํ˜„์ƒ์ด ์ ์–ด์ง„๋‹ค. ์ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด์„œ๋Š” doc/ ๋””๋ ‰ํ† ๋ฆฌ์— ํฌํ•จ๋œ Gitolite ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜๋ผ.

๋ฏธ๋Ÿฌ๋ง: Gitolite์˜ ๋ฏธ๋Ÿฌ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์„œ ์ฃผ ์„œ๋ฒ„๊ฐ€ ๋‹ค์šด ๋ผ๋„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.

Git ๋ฐ๋ชฌ

๊ณต๊ฐœ๋œ ํ”„๋กœ์ ํŠธ๋Š” ๋ˆ„๊ฐ€ ์ฝ๊ธฐ ์ ‘๊ทผ์„ ์‹œ๋„ํ•˜๋Š”์ง€ ์•Œ ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ทธ๋ž˜์„œ HTTP ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ Git ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. Git ํ”„๋กœํ† ์ฝœ์ด HTTP ํ”„๋กœํ† ์ฝœ๋ณด๋‹ค ํšจ์œจ์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค. ๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž์˜ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•ด ์ค€๋‹ค.

๋‹ค์‹œ ๊ฐ•์กฐํ•˜์ง€๋งŒ, ์ด๊ฒƒ์€ ๋ถˆํŠน์ • ๋‹ค์ˆ˜์—๊ฒŒ ์ฝ๊ธฐ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•  ๋•Œ์—๋งŒ ์“ธ๋งŒํ•˜๋‹ค. ๋งŒ์•ฝ ์„œ๋ฒ„๊ฐ€ ์™ธ๋ถ€์— ๊ทธ๋ƒฅ ๋…ธ์ถœ๋ผ ์žˆ์œผ๋ฉด ์šฐ์„  ๋ฐฉํ™”๋ฒฝ์œผ๋กœ ๋ณดํ˜ธํ•˜๊ณ  ํ”„๋กœ์ ํŠธ๋งŒ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ ๋‹ค. ์„œ๋ฒ„๋ฅผ ๋ฐฉํ™”๋ฒฝ์œผ๋กœ ๋ณดํ˜ธํ•˜๊ณ  ์žˆ์œผ๋ฉด CI ์„œ๋ฒ„๋‚˜ ๋นŒ๋“œ ์„œ๋ฒ„๊ฐ™์€ ์ปดํ“จํ„ฐ๋‚˜ ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค์ •ํ•œ๋‹ค. ๋ชจ๋‘ SSH ํ‚ค๋ฅผ ์ผ์ผ์ด ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ๋•Œ ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค.

์–ด์จŒ๋“  Git ํ”„๋กœํ† ์ฝœ์€ ์ƒ๋Œ€์ ์œผ๋กœ ์„ค์น˜ํ•˜๊ธฐ ์‰ฝ๋‹ค. ๊ทธ๋ƒฅ ๋ฐ๋ชฌ์„ ์‹คํ–‰ํ•œ๋‹ค:

git daemon --reuseaddr --base-path=/opt/git/ /opt/git/

--reuseaddr๋Š” ์„œ๋ฒ„๊ฐ€ ๊ธฐ์กด์˜ ์—ฐ๊ฒฐ์ด ํƒ€์ž„์•„์›ƒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ๋ง๊ณ  ๋ฐ”๋กœ ์žฌ์‹œ์ž‘ํ•˜๊ฒŒ ํ•˜๋Š” ์˜ต์…˜์ด๋‹ค. --base-path ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ๋žŒ๋“ค์ด ํ”„๋กœ์ ํŠธ๋ฅผ Cloneํ•  ๋•Œ ์ „์ฒด ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์— ์žˆ๋Š” ๊ฒฝ๋กœ๋Š” ๋…ธ์ถœํ•  ์ €์žฅ์†Œ์˜ ์œ„์น˜๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐฉํ™”๋ฒฝ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉด 9418 ํฌํŠธ๋ฅผ ์—ด์–ด์„œ ์ง€๊ธˆ ์ž‘์—…ํ•˜๋Š” ์„œ๋ฒ„์˜ ์ˆจํ†ต์„ ํ‹”์›Œ์ค€๋‹ค.

์šด์˜์ฒด์ œ์— ๋”ฐ๋ผ Git ๋ฐ๋ชฌ์„ ์‹คํ–‰์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค๋ฅด๋‹ค. ์šฐ๋ถ„ํˆฌ์—์„œ๋Š” Upstart ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ :

/etc/event.d/local-git-daemon

๋‹ค์Œ์˜ ๋‚ด์šฉ์„ ์ž…๋ ฅํ•œ๋‹ค:

start on startup
stop on shutdown
exec /usr/bin/git daemon \
    --user=git --group=git \
    --reuseaddr \
    --base-path=/opt/git/ \
    /opt/git/
respawn

์ €์žฅ์†Œ๋ฅผ ์ฝ์„ ์ˆ˜๋งŒ ์žˆ๋Š” ์‚ฌ์šฉ์ž๋กœ ๋ฐ๋ชฌ์„ ์‹คํ–‰์‹œํ‚ฌ ๊ฒƒ์„ ๋ณด์•ˆ์„ ์œ„ํ•ด ๊ฐ•๋ ฅํ•˜๊ฒŒ ๊ถŒ๊ณ ํ•œ๋‹ค. git-ro๋ผ๋Š” ๊ณ„์ •์„ ์ƒˆ๋กœ ๋งŒ๋“ค๊ณ  ๊ทธ ๊ณ„์ •์œผ๋กœ ๋ฐ๋ชฌ์„ ์‹คํ–‰์‹œํ‚จ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜๋ ค๊ณ  ๊ทธ๋ƒฅ Gitosis๋ฅผ ์‹คํ–‰ํ–ˆ๋˜ git ๊ณ„์ •์œผ๋กœ ์‹คํ–‰์‹œํ‚จ๋‹ค.

์„œ๋ฒ„๊ฐ€ ์žฌ์‹œ์ž‘ํ•  ๋•Œ Git ๋ฐ๋ชฌ์ด ์ž๋™์œผ๋กœ ์‹คํ–‰๋˜๊ณ  ๋ฐ๋ชฌ์ด ์ฃฝ์–ด๋„ ์ž๋™์œผ๋กœ ์žฌ์‹œ์ž‘๋œ๋‹ค. ์„œ๋ฒ„๋Š” ๋†”๋‘๊ณ  Git ๋ฐ๋ชฌ๋งŒ ์žฌ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค:

initctl start local-git-daemon

๋‹ค๋ฅธ ์‹œ์Šคํ…œ์—์„œ๋Š” sysvinit ์‹œ์Šคํ…œ์˜ xinetd ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ž์‹ ๋งŒ์˜ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด์•ผ ํ•œ๋‹ค.

Git ๋ฐ๋ชฌ์„ ํ†ตํ•ด์„œ ์•„๋ฌด๋‚˜ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ Gitosis ์„œ๋ฒ„์— ์•Œ๋ ค์ฃผ์–ด์•ผ ํ•œ๋‹ค. Git ๋ฐ๋ชฌ์œผ๋กœ ์ฝ๊ธฐ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๋Š” ์ €์žฅ์†Œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์„ค์ •์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ๋งŒ์•ฝ iphone_project์— Git ํ”„๋กœํ† ์ฝœ์„ ํ—ˆ์šฉํ–ˆ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒƒ์„ gitosis.conf ํŒŒ์ผ์˜ ํ•˜๋‹จ์— ์ถ”๊ฐ€ํ•œ๋‹ค:

[repo iphone_project]
daemon = yes

์ฐจ๋ก€๋Œ€๋กœ ์ปค๋ฐ‹๊ณผ Pushํ•˜๊ณ  ๋‚˜๋ฉด ์ง€๊ธˆ ์‹คํ–‰ ์ค‘์ธ ๋ฐ๋ชฌ์ด 9418 ํฌํŠธ๋กœ ์ ‘๊ทผํ•˜๋Š” ์‚ฌ๋žŒ์—๊ฒŒ ์„œ๋น„์Šคํ•˜๊ธฐ ์‹œ์ž‘ํ•œ๋‹ค.

Gitosis ์—†์ด๋„ Git ๋ฐ๋ชฌ์„ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๋Ÿฌ๋ ค๋ฉด ์„œ๋น„์Šคํ•˜๊ณ ์ž ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋งˆ๋‹ค ์•„๋ž˜์™€ ๊ฐ™์ด git-daemon-export-ok ํŒŒ์ผ์„ ๋„ฃ์–ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค:

$ cd /path/to/project.git
$ touch git-daemon-export-ok

์ด ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด Git ๋ฐ๋ชฌ์€ ์ธ์ฆ ์—†์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•œ๋‹ค.

๋˜ํ•œ, Gitweb์œผ๋กœ ๋…ธ์ถœํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋„ Gitosis๋กœ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. ๋จผ์ € /etc/gitweb.conf ํŒŒ์ผ์— ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค:

$projects_list = "/home/git/gitosis/projects.list";
$projectroot = "/home/git/repositories";
$export_ok = "git-daemon-export-ok";
@git_base_url_list = ('git://gitserver');

Gitosis ์„ค์ • ํŒŒ์ผ์— gitweb ์„ค์ •์„ ๋„ฃ๊ฑฐ๋‚˜ ๋นผ๋ฉด ์‚ฌ์šฉ์ž๋Š” GitWeb์„ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ๋ฅผ ๋ณผ ์ˆ˜๋„ ์žˆ๊ณ  ๋ชป ๋ณผ ์ˆ˜๋„ ์žˆ๋‹ค.

[repo iphone_project]
daemon = yes
gitweb = yes

์ด์ œ ์ด๊ฒƒ์„ ์ปค๋ฐ‹ํ•˜๊ณ  Pushํ•˜๋ฉด GitWeb์„ ํ†ตํ•ด iphone_project๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Hosted Git

Git ์„œ๋ฒ„๋ฅผ ์„ค์น˜ํ•˜๋Š” ๋“ฑ์˜ ์ผ์„ ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์œผ๋ฉด ์ „๋ฌธ ํ˜ธ์ŠคํŒ… ์‚ฌ์ดํŠธ๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค. ํ˜ธ์ŠคํŒ… ์‚ฌ์ดํŠธ๋Š” ๋ช‡ ๊ฐ€์ง€ ์žฅ์ ์ด ์žˆ๋‹ค. ์„ค์ •์ด ์‰ฌ์›Œ์„œ ๋ฐ”๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ง์ ‘ ์„œ๋ฒ„๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ Git ์„œ๋ฒ„๋ฅผ ์ง์ ‘ ์„ค์น˜ํ•˜๊ณ  ์šด์˜ํ•˜๊ณ  ์žˆ์–ด๋„ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ๋Š” ํ˜ธ์ŠคํŒ… ์‚ฌ์ดํŠธ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ณดํ†ต ์˜คํ”ˆ์†Œ์Šค ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ๋ถ€ํ„ฐ ์ข€ ๋” ์‰ฝ๊ฒŒ ๋„์›€๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

์š”์ฆ˜์€ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ˜ธ์ŠคํŒ… ์‚ฌ์ดํŠธ๋“ค์ด ๋งŽ๋‹ค. ๊ฐ๊ฐ ์žฅ๋‹จ์ ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ ํŽ˜์ด์ง€์—์„œ ์ตœ์‹  ์ •๋ณด๋ฅผ ํ™•์ธํ•ด๋ณด์ž:

https://git.wiki.kernel.org/index.php/GitHosting

์ด ์ ˆ์—์„œ ์ „๋ถ€ ์„ค๋ช…ํ•  ์ˆ˜๋Š” ์—†๊ณ (ํ•„์ž๋Š” ์ € ํšŒ์‚ฌ ์ค‘ ํ•œ๊ตฐ๋ฐ์—์„œ ์ผํ•œ๋‹ค) GitHub์— ๊ณ„์ •๊ณผ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•œ๋‹ค.

GitHub์€ ๊ฐ€์žฅ ํฐ ์˜คํ”ˆ์†Œ์Šค Git ํ˜ธ์ŠคํŒ… ์‚ฌ์ดํŠธ์ด๊ณ  ๊ณต๊ฐœ(Public) ํ”„๋กœ์ ํŠธ์™€ ๋น„๊ณต๊ฐœ(Private) ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ํ˜ธ์ŠคํŒ… ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ณด๊ธฐ ๋“œ๋ฌธ ์‚ฌ์ดํŠธ๋‹ค. ๊ทธ๋ž˜์„œ ์ƒ์—…์šฉ ๋น„๊ณต๊ฐœ ์ฝ”๋“œ์™€ ๊ณต๊ฐœ ์ฝ”๋“œ๋ฅผ ๊ฐ™์€ ๊ณณ์— ๋‘˜ ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ๋กœ ์ด ์ฑ…๋„ GitHub์—์„œ ๋น„๊ณต๊ฐœ๋กœ ์ž‘์„ฑํ–ˆ๋‹ค.

GitHub

GitHub๋Š” ํ”„๋กœ์ ํŠธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ๋‹ค๋ฅธ ์ฝ”๋“œ ํ˜ธ์ŠคํŒ… ์‚ฌ์ดํŠธ๋“ค๊ณผ ๋‹ค๋ฅด๋‹ค. GitHub๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ์‚ฌ์šฉ์ž๊ฐ€ ์ค‘์‹ฌ์ด๋‹ค. GitHub์— grit ํ”„๋กœ์ ํŠธ๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜๊ณ  ์‹ถ์œผ๋ฉด github.com/grit์ด ์•„๋‹ˆ๋ผ github.com/schacon/grit์œผ๋กœ ์ ‘์†ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฒ˜์Œ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•œ ์‚ฌ๋žŒ์ด ๊ทธ ํ”„๋กœ์ ํŠธ๋ฅผ ์žŠ์–ด๋ฒ„๋ ค๋„ ๋ˆ„๊ตฌ๋‚˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์ด์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ํ”„๋กœ์ ํŠธ ์ฃผ ์ €์žฅ์†Œ๋ผ๊ณ  ํ•ด์„œ ํŠน๋ณ„ํ•œ๊ฒŒ ์•„๋‹ˆ๋‹ค.

GitHub์€ ์ด์œค์„ ๋ชฉ์ ์œผ๋กœ ํ•˜๋Š” ํšŒ์‚ฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋น„๊ณต๊ฐœ ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๋ˆ์„ ๋‚ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ, ๋ˆ„๊ตฌ๋‚˜ ์†์‰ฝ๊ฒŒ ๋ฌด๋ฃŒ ๊ณ„์ •์„ ๋งŒ๋“ค์–ด ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค. ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•œ๋‹ค.

๊ณ„์ • ์„ค์ •ํ•˜๊ธฐ

๋จผ์ € ๋ฌด๋ฃŒ ๊ณ„์ •์„ ํ•˜๋‚˜ ๋งŒ๋“ ๋‹ค. ๊ฐ€๊ฒฉ ์ •์ฑ…์— ๋Œ€ํ•ด ์•Œ๋ ค์ฃผ๋ฉฐ ๊ฐ€์ž…์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” https://github.com/pricing์— ๋ฐฉ๋ฌธํ•˜์—ฌ "Sign up" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ฐ€์ž… ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•œ๋‹ค.

๊ทธ๋ฆผ 4-2. GitHub ๊ฐ€๊ฒฉ ์ •์ฑ… ํŽ˜์ด์ง€

์•„์ง ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๊ณ  e-mail ์ฃผ์†Œ์™€ ์•”ํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค(๊ทธ๋ฆผ 4-3).

๊ทธ๋ฆผ 4-3. GitHub ๊ฐ€์ž… ํผ

๊ทธ๋ฆฌ๊ณ  SSH ๊ณต๊ฐœํ‚ค๊ฐ€ ์žˆ์œผ๋ฉด ๋ฐ”๋กœ ๋“ฑ๋กํ•œ๋‹ค. SSH ํ‚ค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ "๋ฐ”๋กœ ์„ค์ •ํ•˜๊ธฐ" ์ ˆ์—์„œ ์ด๋ฏธ ์„ค๋ช…ํ–ˆ๋‹ค. ๊ทธ ๊ณต๊ฐœํ‚ค ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•ด์„œ SSH ๊ณต๊ฐœํ‚ค ์ž…๋ ฅ ๋ฐ•์Šค์— ๋ถ™์—ฌ ๋„ฃ๋Š”๋‹ค. "explain ssh keys" ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด key๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ค€๋‹ค. ์ฃผ์š” ์šด์˜์ฒด์ œ์—์„œ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ชจ๋‘ ์„ค๋ช…๋ผ ์žˆ๋‹ค. "I agree, sign me up" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ž์‹ ๋งŒ์˜ ๋Œ€์‰ฌ๋ณด๋“œ ํŽ˜์ด์ง€๊ฐ€ ๋‚˜ํƒ€๋‚œ๋‹ค.

๊ทธ๋ฆผ 4-4. GitHub ์‚ฌ์šฉ์ž ๋Œ€์‰ฌ๋ณด๋“œ

๊ทธ๋ฆฌ๊ณ  ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค์ž.

์ €์žฅ์†Œ ๋งŒ๋“ค๊ธฐ

Your Repositories์˜†์— ์žˆ๋Š” "create a new one" ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“œ๋Š” ์ž…๋ ฅ ํผ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค(๊ทธ๋ฆผ 4-5).

๊ทธ๋ฆผ 4-5. GitHub์˜ ์ €์žฅ์†Œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํผ

์ด ํผ์— ํ”„๋กœ์ ํŠธ ์ด๋ฆ„๊ณผ ํ”„๋กœ์ ํŠธ ์„ค๋ช…์„ ์ ๋Š”๋‹ค. ๋‹ค ์ ์€ ํ›„์— "Create Repository" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด GitHub์— ์ €์žฅ์†Œ๊ฐ€ ์ƒ๊ธด๋‹ค.

๊ทธ๋ฆผ 4-6. GitHub ํ”„๋กœ์ ํŠธ ์ •๋ณด

์ด ์ €์žฅ์†Œ์—๋Š” ์•„์ง ์ฝ”๋“œ๊ฐ€ ์—†์–ด์„œ GitHub์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•, ์ด๋ฏธ ์žˆ๋Š” Git ํ”„๋กœ์ ํŠธ๋ฅผ Pushํ•˜๋Š” ๋ฒ•, ๊ณต๊ฐœ๋œ Subversion ์ €์žฅ์†Œ์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”(Import) ๋ฐฉ๋ฒ• ๋“ฑ์„ ๋ณด์—ฌ์ค€๋‹ค.

๊ทธ๋ฆผ 4-7. ์ƒˆ ์ €์žฅ์†Œ๋ฅผ ์œ„ํ•œ ์‚ฌ์šฉ์„ค๋ช…์„œ

์—ฌ๊ธฐ ์„ค๋ช…ํ•˜๋Š” ๋‚ด์šฉ์€ ์ด๋ฏธ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์› ๋‹ค. ํ”„๋กœ์ ํŠธ๊ฐ€ ์—†์„ ๋•Œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค:

$ git init
$ git add .
$ git commit -m 'initial commit'

๋งŒ์•ฝ ์ด๋ฏธ ๋กœ์ปฌ์— Git ์ €์žฅ์†Œ๊ฐ€ ์žˆ์œผ๋ฉด GitHub ์ €์žฅ์†Œ๋ฅผ ๋ฆฌ๋ชจํŠธ ์ €์žฅ์†Œ๋กœ ๋“ฑ๋กํ•˜๊ณ  master ๋ธŒ๋žœ์น˜๋ฅผ Pushํ•œ๋‹ค:

$ git remote add origin git@GitHub.com:testinguser/iphone_project.git
$ git push origin master

์ด์ œ ํ”„๋กœ์ ํŠธ๊ฐ€ GitHub์—์„œ ์„œ๋น„์Šค๋˜๋‹ˆ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ์—๊ฒŒ URL์„ ์•Œ๋ ค ์ฃผ๋ฉด ๋œ๋‹ค. URL์€ http://github.com/testinguser/iphone_project์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ์ €์žฅ์†Œ์˜ ์ •๋ณด๋ฅผ ์ž˜ ์‚ดํŽด๋ณด๋ฉด Git URL์ด ๋‘ ๊ฐœ๋ผ๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆผ 4-8. ํ”„๋กœ์ ํŠธ์˜ ๊ณต๊ฐœ URL๊ณผ ๋น„๊ณต๊ฐœ URL

Public Clone URL์€ ๋ง ๊ทธ๋Œ€๋กœ ๋ˆ„๊ตฌ๋‚˜ ํ”„๋กœ์ ํŠธ๋ฅผ Cloneํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ชจ๋‘์—๊ฒŒ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ๊ณต๊ฐœํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด URL์„ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์— ์•Œ๋ ค์ฃผ๊ฑฐ๋‚˜ ์›น์‚ฌ์ดํŠธ ๊ฐ™์€๋ฐ ๊ณต๊ฐœํ•˜๋Š” ๊ฒƒ์„ ๋ถ€๋‹ด์Šค๋Ÿฌ์›Œ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

Your Clone URL์€ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๋Š” SSH ๊ธฐ๋ฐ˜ URL์ด๋‹ค. ์‚ฌ์šฉ์ž ๊ณ„์ •์— ๋“ฑ๋กํ•œ ๊ณต๊ฐœํ‚ค์™€ ํ•œ ์ง์ธ ๊ฐœ์ธํ‚ค๋กœ๋งŒ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋กœ ์ด ํ”„๋กœ์ ํŠธ์— ๋ฐฉ๋ฌธํ•˜๋ฉด ์ด URL์€ ๋ณผ ์ˆ˜ ์—†๊ณ  ๊ณต๊ฐœ URL๋งŒ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Subversion์œผ๋กœ๋ถ€ํ„ฐ ์ฝ”๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ(Import)

GitHub์€ ๊ณต๊ฐœ ์ค‘์ธ Subversion ํ”„๋กœ์ ํŠธ๋ฅผ Git ํ”„๋กœ์ ํŠธ๋กœ ๋งŒ๋“ค์–ด ์ค€๋‹ค. ์‚ฌ์šฉ์„ค๋ช…์„œ ํ•˜๋‹จ์— ์žˆ๋Š” "Subversion์—์„œ Importํ•˜๊ธฐ" ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ž„ํฌํŠธ ํผ์„ ๋ณผ ์ˆ˜ ์žˆ๊ณ  ๊ฑฐ๊ธฐ์— Subversion ํ”„๋กœ์ ํŠธ์˜ URL์„ ๋„ฃ๋Š”๋‹ค(๊ทธ๋ฆผ 4-9).

๊ทธ๋ฆผ 4-9. Subversion ํ”„๋กœ์ ํŠธ๋ฅผ Importํ•˜๋Š” ํ™”๋ฉด

ํ”„๋กœ์ ํŠธ๊ฐ€ ๋น„ํ‘œ์ค€ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๊ทœ๋ชจ๊ฐ€ ๋„ˆ๋ฌด ํฌ๊ณ  ๋น„๊ณต๊ฐœ๋ผ๋ฉด ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. _7์žฅ_์—์„œ ์ˆ˜๋™์œผ๋กœ ์ž„ํฌํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ข€ ๋” ์ž์„ธํžˆ ๋ฐฐ์šด๋‹ค.

๋™๋ฃŒ ์ถ”๊ฐ€ํ•˜๊ธฐ

๋™๋ฃŒ๋ฅผ ์ถ”๊ฐ€ํ•˜์ž. ๋จผ์ € John์”จ, Josie์”จ, Jessica์”จ๋ฅผ ๋ชจ๋‘ GitHub์— ๊ฐ€์ž…์‹œํ‚ค๊ณ  ๋‚˜์„œ ๊ทธ๋“ค์„ ๋™๋ฃŒ๋กœ ์ถ”๊ฐ€ํ•˜๊ณ  ์ €์žฅ์†Œ์— Pushํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ์ค€๋‹ค.

ํ”„๋กœ์ ํŠธ ํŽ˜์ด์ง€์— ์žˆ๋Š” Admin ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด์„œ ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•œ๋‹ค(๊ทธ๋ฆผ 4-10).

๊ทธ๋ฆผ 4-10. GitHub์˜ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ ํŽ˜์ด์ง€

๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ์“ฐ๊ธฐ ๊ถŒํ•œ์„ ์ฃผ๋ ค๋ฉด โ€œAdd another collaboratorโ€ ๋งํฌ๋ฅผ ํด๋ฆญํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ํ…์ŠคํŠธ ๋ฐ•์Šค๊ฐ€ ์ƒˆ๋กœ ๋‚˜ํƒ€๋‚˜๋Š” ๋ฐ ๊ฑฐ๊ธฐ์— ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์ž…๋ ฅํ•œ๋‹ค. ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด ์ž๋™์œผ๋กœ ์‹œ์Šคํ…œ์— ์กด์žฌํ•˜๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์ฐพ์•„์„œ ๋ณด์—ฌ ์ค€๋‹ค. ์›ํ•˜๋Š” ์‚ฌ์šฉ์ž๋ฅผ ์ฐพ์œผ๋ฉด Add ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด์„œ ๊ทธ ์‚ฌ์šฉ์ž๋ฅผ ๋™๋ฃŒ๋กœ ๋งŒ๋“ ๋‹ค.

๊ทธ๋ฆผ 4-11. ํ”„๋กœ์ ํŠธ์— ๋™๋ฃŒ ์ถ”๊ฐ€ํ•˜๊ธฐ

์ถ”๊ฐ€ํ•œ ์‚ฌ๋žŒ์€ ๋™๋ฃŒ ๋ชฉ๋ก ๋ฐ•์Šค์—์„œ ๋ชจ๋‘ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค(๊ทธ๋ฆผ 4-12).

๊ทธ๋ฆผ 4-12. ํ”„๋กœ์ ํŠธ ๋™๋ฃŒ๋“ค

๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ ๋‹ค์‹œ ํ˜ผ์ž ์ž‘์—…ํ•˜๊ณ  ์‹ถ์–ด์ง€๋ฉด "revoke" ๋งํฌ๋ฅผ ํด๋ฆญํ•˜์—ฌ ์ซ“์•„๋‚ธ๋‹ค. ์ซ“๊ฒจ๋‚˜๋ฉด ๋”๋Š” Pushํ•  ์ˆ˜ ์—†๋‹ค. ๋˜ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ๋“ฑ๋ก๋œ ๋™๋ฃŒ๋ฅผ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์–ด ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

๋‚ด ํ”„๋กœ์ ํŠธ

Subversion์—์„œ Importํ–ˆ๊ฑฐ๋‚˜ ๋กœ์ปฌ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ Pushํ•˜๊ณ  ๋‚˜๋ฉด ํ”„๋กœ์ ํŠธ ๋ฉ”์ธ ํŽ˜์ด์ง€๊ฐ€ ๊ทธ๋ฆผ 4-13๊ฐ™์ด ๋ฐ”๋€๋‹ค.

๊ทธ๋ฆผ 4-13. GitHub์˜ ํ”„๋กœ์ ํŠธ ๋ฉ”์ธ ํŽ˜์ด์ง€

์‚ฌ๋žŒ๋“ค์ด ์ด ํ”„๋กœ์ ํŠธ์— ๋ฐฉ๋ฌธํ•˜๋ฉด ์ด ํŽ˜์ด์ง€๊ฐ€ ์ œ์ผ ์ฒ˜์Œ ๋ณด์ธ๋‹ค. ์ด ํŽ˜์ด์ง€๋Š” ๋ช‡ ๊ฐ€์ง€ ํƒญ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. Commits ํƒญ์€ ์ง€๊ธˆ๊นŒ์ง€์˜ ์ปค๋ฐ‹์„ git log ๋ช…๋ น์„ ์‹คํ–‰์‹œํ‚จ ๊ฒƒ์ฒ˜๋Ÿผ ์ตœ์‹  ๊ฒƒ๋ถ€ํ„ฐ ๋ณด์—ฌ์ค€๋‹ค. Network ํƒญ์€ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ณต์ œํ•œ ์‚ฌ๋žŒ๋“ค๊ณผ ๊ธฐ์—ฌํ•œ ์‚ฌ๋žŒ๋“ค์„ ๋ชจ๋‘ ๋ณด์—ฌ์ค€๋‹ค. Downloads ํƒญ์—๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์ด๋‚˜ ํ”„๋กœ์ ํŠธ์˜ ํƒœ๊ทธ ๋ฒ„์ „์„ ์••์ถ•ํ•ด์„œ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋‹ค. Wiki ํƒญ์€ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ์ •๋ณด๋‚˜ ๋ฌธ์„œ๋ฅผ ์“ฐ๋Š” ๊ณณ์ด๋‹ค. Graphs ํƒญ์€ ์‚ฌ๋žŒ๋“ค์˜ ํ™œ๋™์„ ๊ทธ๋ฆผ๊ณผ ํ†ต๊ณ„๋กœ ๋ณด์—ฌ์ค€๋‹ค. ๋ฉ”์ธ ํƒญ์ธ Source ํƒญ์€ ํ”„๋กœ์ ํŠธ์˜ ๋ฉ”์ธ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  README ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด ์ž๋™์œผ๋กœ ํ™”๋ฉด์— ์ถœ๋ ฅํ•ด ์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰ ์ปค๋ฐ‹ ๋‚ด์šฉ๋„ ํ•จ๊ป˜ ๋ณด์—ฌ์ค€๋‹ค.

ํ”„๋กœ์ ํŠธ Fork

๊ถŒํ•œ์ด ์—†๋Š” ํ”„๋กœ์ ํŠธ์— ์ฐธ์—ฌํ•˜๊ณ  ์‹ถ์œผ๋ฉด GitHub๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ Forkํ•˜๋„๋ก ๊ถŒ๊ณ ํ•œ๋‹ค. ๋งˆ์นจ ๋งค์šฐ ํฅ๋ฏธ๋กญ๊ฒŒ ๋ณด์ด๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ๋‹ค๊ณ  ํ•˜์ž. ๊ทธ ํ”„๋กœ์ ํŠธ๋ฅผ ์กฐ๊ธˆ ๋œฏ์–ด๊ณ ์น˜๋ ค๋ฉด ํ”„๋กœ์ ํŠธ ํŽ˜์ด์ง€ ์ƒ๋‹จ์— ์žˆ๋Š” "fork" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด GitHub๋Š” ์ ‘์†ํ•œ ์‚ฌ์šฉ์ž์˜ ๊ณ„์ •์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ Forkํ•ด ์ค€๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ด ํ”„๋กœ์ ํŠธ์— ๋งˆ์Œ๋Œ€๋กœ Pushํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ตณ์ด Pushํ•  ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ๋žŒ๋“ค์„ ๋™๋ฃŒ๋กœ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ์‚ฌ๋žŒ๋“ค์€ ๋งˆ์Œ๊ป ํ”„๋กœ์ ํŠธ๋ฅผ Forkํ•˜๊ณ  Pushํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์›๋ž˜ ํ”„๋กœ์ ํŠธ์˜ ๊ด€๋ฆฌ์ž๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฆฌ๋ชจํŠธ ์ €์žฅ์†Œ๋กœ ์ถ”๊ฐ€ํ•˜๊ณ  ๊ทธ ์ž‘์—…๋ฌผ์„ ๊ฐ€์ ธ์™€์„œ Mergeํ•œ๋‹ค.

ํ”„๋กœ์ ํŠธ ํŽ˜์ด์ง€์— ๋“ค์–ด๊ฐ€์„œ ์ƒ๋‹จ์˜ "fork" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ณต์ œํ•œ๋‹ค(๊ทธ๋ฆผ 4-14) ๊ทธ๋ฆผ 4-14์˜ ์˜ˆ๋Š” mojombo/chronic ํ”„๋กœ์ ํŠธ ํŽ˜์ด์ง€์ด๋‹ค

๊ทธ๋ฆผ 4-14. ์–ด๋–ค ์ €์žฅ์†Œ๋“ ์ง€ "fork" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด Pushํ•  ์ˆ˜ ์žˆ๋Š” ์ €์žฅ์†Œ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค

ํด๋ฆญํ•˜๋Š” ์ˆœ๊ฐ„, ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ฆ‰์‹œ Forkํ•œ๋‹ค(๊ทธ๋ฆผ 4-15).

๊ทธ๋ฆผ 4-15. Forkํ•œ ํ”„๋กœ์ ํŠธ

GitHub ์š”์•ฝ

๋นจ๋ฆฌ ํ•œ๋ฒˆ ์ „์ฒด๋ฅผ ํ›‘์–ด๋ณด๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์—์„œ๋Š” GitHub์— ๋Œ€ํ•ด ์ด ์ •๋„๋กœ๋งŒ ์„ค๋ช…ํ–ˆ๋‹ค. ๋ช‡ ๋ถ„ ๋งŒ์— ๊ณ„์ •๊ณผ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  Push๊นŒ์ง€ ํ•  ์ˆ˜ ์žˆ๋‹ค. GitHub์— ์žˆ๋Š” ๊ฐœ๋ฐœ์ž ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ทœ๋ชจ๋Š” ๋งค์šฐ ํฌ๊ธฐ ๋•Œ๋ฌธ์— ๋งŒ์•ฝ GitHub์— ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์ด ๋‹น์‹ ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ณต์ œํ•˜๊ณ  ๋‹น์‹ ์„ ๋„์šธ ๊ฒƒ์ด๋‹ค. GitHub๋Š” Git์„ ๋นจ๋ฆฌ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š”๋‹ค.

์š”์•ฝ

๋ฆฌ๋ชจํŠธ ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค๊ณ  ๋‹ค๋ฅธ ์‚ฌ๋žŒ๊ณผ ํ˜‘์—…ํ•˜๊ฑฐ๋‚˜ ์ž‘์—…๋ฌผ์„ ๊ณต๊ฐœํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๋‹ค.

์„œ๋ฒ„๋ฅผ ์ง์ ‘ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์€ ํ•  ์ผ์ด ๋งŽ์€๋ฐ๋‹ค๊ฐ€ ๋ฐฉํ™”๋ฒฝ๋„ ํ•„์š”ํ•˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ ‡๊ฒŒ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ์ผ์€ ์‹œ๊ฐ„์ด ๋งŽ์ด ๋“ ๋‹ค. ํ˜ธ์ŠคํŒ… ์‚ฌ์ดํŠธ๋ฅผ ์ด์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ฝ”๋“œ๋ฅผ ํƒ€์ธ์˜ ์„œ๋ฒ„์— ๋ณด๊ด€ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์กฐ์ง๋“ค์ด ๋งŽ๋‹ค.

์ž์‹ ์˜ ์กฐ์ง์—์„œ ์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ ํ˜‘์—…ํ•ด์•ผ ํ• ์ง€ ๊ณ ๋ฏผํ•ด์•ผ ํ•˜๋Š” ์‹œ์ ์ด ๋˜์—ˆ๋‹ค.

Last updated

Was this helpful?