gitã®åŸºæœ¬çš„ãªä½¿ã„æ–¹ === * æ¦‚è¦ gitã®èª¬æ˜Žã¯å¤šã€…ã‚ã‚‹ãŒã€è¤‡æ•°ã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ¬ãƒã‚¸ãƒˆãƒªã‚’使ã£ãŸæ“作ã«ã¤ã„ã¦è§¦ã‚Œã‚‰ã‚Œã¦ã„ã‚‹ã‚‚ã®ã¯å°‘ãªã„。 ãã®ãŸã‚ã€ãƒ‰ã‚ュメント化ã™ã‚‹ã€‚ * シナリオ(ã“ã˜ã¤ã‘) ã»ã’社ã§ã¯gitを使ã£ã¦hogewareã¨ã„ã†ã‚¢ãƒ—リを開発をã—ã¦ã„ãŸã€‚ ã‚ã‚‹æ—¥ã€ã¨ã‚る機能ã®é–‹ç™ºã‚’外注ã§é ¼ã‚“ã 。 ã¤ã¾ã‚Šã€è‡ªç¤¾ã§ã‚‚ã¨ã‚‚ã¨ãƒ¬ãƒã‚¸ãƒˆãƒªã‚’æŒã£ã¦ã„ãŸãŒã€ ã‚るタイミングã§ãã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’外ã«å‡ºã™ã€‚ ãã®ã‚ã¨ã€å®Œæˆå“を自分ã®ãƒ¬ãƒã‚¸ãƒˆãƒªã«ãƒžãƒ¼ã‚¸ã—ãŸã„。 ã“ã®å·®ç•°ã€ä¸é–“ã®commit(変更履æ´)ã¯ã‚‚らã†å¿…è¦ãŒãªã„。(もらã£ãŸã£ã¦ã„ã„) * 剿 ``` $ git config --global push.default matching ``` * 親プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’ã¤ãã‚‹ ``` ### ã“ã“ã‹ã‚‰ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆãŒå§‹ã¾ã‚‹ï¼ˆãƒ¬ãƒã‚¸ãƒˆãƒªã‚’作りã¾ã™) $ mkdir -p repos/hogeware $ cd repos/hogeware $ git --bare init Initialized empty Git repository in /home/kanai/repos/hogeware/ ### 作æ¥ç”¨ãƒ¬ãƒã‚¸ãƒˆãƒªã‚’作りãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆ $ mkdir ~/workdir/ $ cd ~/workdir/ $ git clone file:///home/kanai/repos/hogeware/ Cloning into 'hogeware'... $ cd hogeware/ ### 最åˆã®commitã‚’ã—ã¾ã™(Changelogã¨source1ã¨ã„ã†ãƒ•ァイルをcommit) $ echo "init" > Changelog $ echo "#include<stdio.h>" > source1.c $ git add . $ git commit -m "init" ### ã“ã“ã¾ã§ã§MasterãŒã§ããŸã€‚ ### Branchを切ã£ã¦ticket1ã¨ã„ã†ãƒ‘ッãƒã‚’ã¤ãã‚‹ $ git branch ticket1 $ git checkout ticket1 Switched to branch 'ticket1' $ cat "#include<stdlib.h>" >> source1.c $ echo "#include<stdlib.h>" >> source1.c $ echo "#include<stdio.h>" >> source2.c $ git commit -m "working" On branch ticket1 $ git add . $ git commit -m "working" [ticket1 ff36d86] working ### ticket1ã¯ã¾ã 完æˆã—ã¦ã„ãªãã¦ã€ã‚‚ã†å°‘ã—å¤‰æ›´ã‚’åŠ ãˆãŸã¨ã—ã¾ã™ $ echo "ticket1 done" >> Changelog $ git add . $ git commit -m "finish #1" [ticket1 3cac89f] finish #1 ### ticket1ã®å¤‰æ›´ãŒçµ‚ã‚ã£ãŸã®ã§masterã«merge $ git checkout master $ git diff ticket1 > ã‚ã¦ã‚‹ãƒ‘ッãƒã‚’比較 $ git merge --no-ff ticket1 -m "merge ticket1" > master Branchã«å¯¾ã—ã¦ï¼ˆï¼ä»Šã®Branch)ã«ticket1ã‚’mergeã—ã¾ã™ã€‚ ### 以上ã§ã¯ã€masterブランãƒã‚’開発用ã«ã—ã¦ããŸã€‚ã—ã‹ã—〠### 今後ã€Developmentã§é–‹ç™ºã™ã‚‹æ°—ã«ãªã£ã¦ã㟠$ git branch development $ git checkout development > ã“ã®Branchã¯masterã‹ã‚‰branchã—ãŸã‚‚ã®ãªã®ã§ã€ > ã“ã®æ™‚点ã§ã¯masterã§ã‚ã‚‹ ### ã›ã£ã‹ããªã®ã§ã€commit logã‚’ã‚‚ã†ä¸€å€‹ä½œã‚‹ã€‚ ### Ticket2ã¨ã„ã†Bnrachを切ã£ã¦developmentã«commit $ git branch ticket2 $ git checkout ticket2 $ echo "main(){printf("hoge");}" >> source2.c $ echo "ticket2 finish" >> Changelog $ git add . $ git commit -m "finish #2" ### 終ã‚ã£ãŸã®ã§developmentã«merge $ git checkout development $ git merge --no-ff ticket2 -m "merge #2" ### ã“ã“ã§ã€è‡ªåˆ†ã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ¬ãƒã‚¸ãƒˆãƒªã«æœ€æ–°ã‚’pushã™ã‚‹ ### tagã‚’ãã£ã¦push $ git tag 0.0 $ git push origin master $ git push origin development $ git push --tag $ git branch -a * development master ticket1 ticket2 remotes/origin/development remotes/origin/masterxx ``` * 開発先ã¸ã®ãƒ‡ãƒ—ãƒã‚¤ ã“ã“ã§ã€ã»ã’社ã¯é–‹ç™ºå…ˆã‚‚ã’社ã«è³‡æã‚’渡ã™ã€‚ ã“ã¡ã‚‰ã§ã¯ã“ã¡ã‚‰ã§ã®ç®¡ç†ã‚’ã—ãŸã„。 ``` @mieru2 ### ã‚‚ã’社ã§ã¯ã€è‡ªç¤¾ã§ãƒ¬ãƒã‚¸ãƒˆãƒªã‚µãƒ¼ãƒã‚’ç«‹ã¦ã‚‹ã€‚ ### 通常ã®cloneã§ã¯ã€non-bareã«ãªã‚‹ã®ã§ã€bareã§ä½œæˆã™ã‚‹(pushå¯èƒ½) $ git clone --bare 192.168.9.99:~/workdir/hogeware hogeware Cloning into bare repository 'hogeware'... ### mieru2ã¯ãƒ¬ãƒã‚¸ãƒˆãƒªã‚µãƒ¼ãƒã§ã‚りã€workdirã‚‚æŒã¤ã€‚ ### checkout用ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’ã¤ãりã€cloneã™ã‚‹ã€‚(ã“れã¯non-bare) $ mkdir ~/workdir $ cd ~/workdir $ git clone file:///home/kanai/repos/hogeware $ git branch -a * development ``` 次ã«ã€ã‚‚ã’社ã¯ã€å®—教的ã«masterを開発用ã«ã—ã¦ã„ã‚‹ã®ã§ã€è‡ªåˆ†ã®ãƒ–ランãƒã¯ development = masterã«ã—ãŸã„ã¨ã™ã‚‹ã€‚ ``` $ git push origin :master # developmentã«å…¥ã£ã¦ã€ã“ã“ã‹ã‚‰æ´¾ç”Ÿã‚’行ㆠ$ git checkout development $ git remote set-head origin development > masterを一度消ã—ãŸã„ã®ã§ã€headã‚’developmentã«å‘ã‘ã‚‹ $ git branch -a * development $ git branch -D master > masterを消㙠Deleted branch master (was 9d126d7). $ git push origin :master > originã‹ã‚‰masterを削除ã™ã‚‹ To file:///home/kanai/repos/hogeware - [deleted] master $ git branch -m development master > masterã‚’developmentã«renameã™ã‚‹ $ git branch -a * master remotes/origin/HEAD -> origin/development remotes/origin/development remotes/origin/ticket1 remotes/origin/ticket2 ### ã“ã®æ™‚点ã§ã¯ã€localã®masterã¯ï¼ˆrenameå‰ã®)origin/developmentã‚’ã‚€ã„ã¦ã„ã‚‹ $ git push origin master Total 0 (delta 0), reused 0 (delta 0) To file:///home/kanai/repos/hogeware * [new branch] master -> master ### HEAD(remote)ã®å‘ã先を変ãˆã‚‹ $ git remote set-head origin master $ git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/development remotes/origin/master remotes/origin/ticket1 remotes/origin/ticket2 #$ git pull origin master # From file:///home/kanai/repos/hogeware # * branch master -> FETCH_HEAD # Already up-to-date. ### ã¡ã‚ƒã‚“ã¨developmentã®å†…容ãŒåæ˜ ã•れã¦ã„ã‚‹ $ tail Changelog init ticket1 done ticket2 finish ### ã“ã®ã¾ã¾ã ã¨ã€pushå…ˆã¯origin/developmentã«ãªã‚‹ $ git branch -vv issue101 6b0b1ad solve issue #101 issue102 0ec50bc #102 * master d8bcc0e [origin/development: ahead 2] merge #101 release e5f1387 merge #2 $ $ git push -u origin master Branch master set up to track remote branch master from origin. Everything up-to-date $ git branch -vv issue101 6b0b1ad solve issue #101 issue102 0ec50bc #102 * master d8bcc0e [origin/master] merge #101 release e5f1387 merge #2 ``` ã“れã§ã€ä¸€å¿œã€developmentã‚’masterã«ã™ã‚‹ã“ã¨ãŒã§ãる。(ã‚„ã‚‹å¿…è¦ãŒã‚ã‚‹ã®ã‹ã¯åˆ¥ã®è©±) 開発å´ã§å°‘ã—ã„ã˜ã£ã¦ã¿ã‚‹ã€‚開発å´ã¯releaseã¨ã„ã†ãƒ–ランãƒã§é–‹ç™ºå…ƒã«ã‚³ãƒ¼ãƒ‰ã‚’å¼•ãæ¸¡ã—ãŸã„。 ã¨ã‚Šã‚ãˆãšã€release branchã ã‘ã¤ãる。 ã¤ã„ã§ã«ã€é–‹ç™ºå…ƒã§ã‚„ã£ã¦ãŸpatchブランãƒã¯ã„らãªã„ã®ã§æ¶ˆã™ã€‚ ``` @mieru2 ### ã„らãªã„ã®æ¶ˆã™ $ git branch release $ git push origin release Total 0 (delta 0), reused 0 (delta 0) To file:///home/kanai/repos/hogeware * [new branch] release -> release $ git push origin :ticket1 To file:///home/kanai/repos/hogeware - [deleted] ticket1 $ git push origin :ticket2 To file:///home/kanai/repos/hogeware - [deleted] ticket2 $ git branch -a * master release remotes/origin/HEAD -> origin/master remotes/origin/development remotes/origin/master remotes/origin/release ``` ã“ã“ã§ã€remoteã®HEADã‚’ã‹ãˆã‚‹ ``` ### developmentを消ãã†ã¨ã™ã‚‹ã¨ã‚¨ãƒ©ãƒ¼ã¨ãªã‚‹ ### ã“れã¯ã€remoteã®origin/HEADãŒdevelopmentã‚’ã‚€ã„ã¦ã„ã‚‹ãŸã‚ $ git push origin :development remote: error: By default, deleting the current branch is denied, because the next remote: error: 'git clone' won't result in any file checked out, causing confusion. remote: error: remote: error: You can set 'receive.denyDeleteCurrent' configuration variable to remote: error: 'warn' or 'ignore' in the remote repository to allow deleting the remote: error: current branch, with or without a warning message. remote: error: remote: error: To squelch this message, you can set it to 'refuse'. remote: error: refusing to delete the current branch: refs/heads/development To file:///home/kanai/repos/hogeware ! [remote rejected] development (deletion of the current branch prohibited) error: failed to push some refs to 'file:///home/kanai/repos/hogeware' ### ã“ã®æ§˜åを確èªã™ã‚‹ $ git remote show origin * remote origin Fetch URL: file:///home/kanai/repos/hogeware Push URL: file:///home/kanai/repos/hogeware HEAD branch: development Remote branches: development tracked master tracked release tracked Local branch configured for 'git pull': master merges with remote master Local refs configured for 'git push': master pushes to master (up to date) release pushes to release (up to date) ``` ã„ãã¤ã‹ã‚„り方ã¯ã‚ã‚‹ãŒã€reposå´ã§track先を変ãˆã‚‹ã€‚ ``` @mieru2: ã“れã¯ãƒ¬ãƒã‚¸ãƒˆãƒªå†…ã§ã®æ“作 $ cd ~/repos/hogeware/ $ git symbolic-ref HEAD refs/heads/master @mieru2: 作æ¥ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§remoteを確èªã™ã‚‹ $ cd ~/workdir/hogeware/ $ git remote show origin * remote origin Fetch URL: file:///home/kanai/repos/hogeware Push URL: file:///home/kanai/repos/hogeware HEAD branch: master ★trackå…ˆãŒmasterã«ãªã£ã¦ã„ã‚‹ Remote branches: development tracked master tracked release tracked Local branch configured for 'git pull': master merges with remote master Local refs configured for 'git push': master pushes to master (up to date) release pushes to release (up to date) ### ã“れã§ã€remote origin/masterã¯masterãªã®ã§ã€deleteã™ã‚‹ $ git push origin :development To file:///home/kanai/repos/hogeware - [deleted] development ``` 折角ãªã®ã§ã€masterã§é–‹ç™ºã—ã¦ã¿ã‚‹ã€‚ ``` @mieru2 $ git branch issue101 $ git checkout issue101 $ echo "issue101 finish" >> Changelog $ echo "int main(){}" >> source1.c $ git add . $ git commit Aborting commit due to empty commit message. $ git checkout master $ git commit -m "solve issue #101" $ git merge --no-ff issue101 -m "merge #101" Merge made by the 'recursive' strategy. Changelog | 1 + source1.c | 1 + 2 files changed, 2 insertions(+) $ git branch issue 102 $ git checkout issue102 $ echo "102" >> Changelog $ git add . $ git checkout master $ git commit -m "#102" $ git merge --no-ff issue101 -m "merge #101" $ git branch -D issue102 Deleted branch issue102 (was 0ec50bc). $ git branch -D issue101 Deleted branch issue101 (was 6b0b1ad). $ git push e5f1387..d8bcc0e master -> master ``` ã“ã“ã§ã€é–‹ç™ºå…ˆã¯ã€ã‚‚ã†ä¸€å°ã®PCã«é–‹ç™ºå…ˆã®ãƒ¬ãƒã‚¸ãƒˆãƒªã‚’è½ã¨ã™ã€‚ ``` @mieru3 ### ã“ã¡ã‚‰ã¯é–‹ç™ºç”¨ãªã®ã§ã€non-bare $ git clone ssh://192.168.9.98//home/kanai/repos/hogeware $ cd hogeware $ git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/master remotes/origin/release ``` ãれãžã‚Œã§ç«¶åˆã—ãªã„パッãƒã‚’ã‚ã¦ã¦ã€masterツリーã«pushã—ã¦ã¿ã‚‹ã€‚ ã“ã“ã§ã®é–‹ç™ºæ–¹æ³•ã¯master=開発先ã«å¯¾ã—ã¦ã€localã§mergeã—ã¦ã‹ã‚‰pushã™ã‚‹æ–¹æ³•を考ãˆã‚‹ã€‚ ``` ### mieru2å´ã§ã®ä½œæ¥ @mieru2 $ git branch mieru2-101 $ git checkout mieru2-101 $ echo "/* 101 */" >> source1.c $ git add . $ git commit -m '101' $ git checkout master $ git merge --no-ff mieru2-101 $ git push 5bc1c15..92e56e3 master -> master ### ã“ã“ã¾ã§ã§ã€mieru2ã®å¤‰æ›´ã¯ ### mieru3å´ã§ã®ä½œæ¥ @mieru3 $ git branch mieru3-102 $ git checkout mieru3-102 $ echo "/* 102 */" >> source2.c $ git add . $ git commit -m "102" $ git merge --no-ff mieru3-102 $ git push kanai@192.168.9.98's password: To ssh://192.168.9.98//home/kanai/repos/hogeware ! [rejected] master -> master (fetch first) ### ã“れã¯ã€å˜ã«ã€æœ€æ–°ã¨ã¶ã¤ã‹ã£ãŸã ã‘ ### mieru3ãŒã‚ã§merge作æ¥ã™ã‚‹ ### ã¨ã„ã†ã‚‚ã®ã®ã€conflictã—ã¦ã„ãªã„ã®ã§ã€å˜ã«mergeã™ã‚‹ã ã‘。 @mieru3 $ git fetch -p 5bc1c15..92e56e3 master -> origin/master $ git merge --no-ff origin/master Merge made by the 'recursive' strategy. $ git push 92e56e3..3a79f95 master -> master ``` ã“ã®ã‚ˆã†ã«é–‹ç™ºã‚’行ã£ãŸã‚‰ã€releaseブランãƒã‚’切る。(å—ã‘æ¸¡ã—用) ``` @mieru2 $ git checkout release $ git log | grep "commit " | wc -l 6 $ git merge --no-ff master -m "RELEASE-0.1" $ git log | grep "commit " | wc -l 16 > masterã®logツリーãŒå–り込ã¾ã‚ŒãŸã“ã¨ãŒåˆ†ã‹ã‚‹ $ git push e5f1387..137453c release -> release e$ git tag 0.1 $ git push --tags Total 0 (delta 0), reused 0 (delta 0) To file:///home/kanai/repos/hogeware * [new tag] 0.1 -> 0.1 ``` ã“ã“ã§ã€é–‹ç™ºå…ˆã¯é–‹ç™ºãŒçµ‚ã‚ã£ãŸã€‚ã“ã‚“ã©ã¯ã€é–‹ç™ºå…ƒãŒã“ã®å¤‰æ›´ã‚’å–り込む。 ``` ### mieru1 @mieru1 $ git fetch -p # remoteã®ãƒ¬ãƒã‚¸ãƒˆãƒªã‚’登録ã™ã‚‹ $ git remote add mieru2 ssh://192.168.9.98//home/kanai/workdir/hogeware # mieru1å´ã§mieru2ã®ãƒ–ランãƒã‚’pullã™ã‚‹ $ git fetch mieru2 release * branch release -> FETCH_HEAD * [new branch] release -> mieru2/release $git fetch --tags mieru2 release kanai@192.168.9.98's password: From ssh://192.168.9.98//home/kanai/workdir/hogeware * branch release -> FETCH_HEAD # mieru1ã§release㨠$ git merge --no-ff 0.1 Merge made by the 'recursive' strategy. $ git push e5f1387..92a3e59 development -> development ```