Git是一個分佈式的代碼管理庫,linux之父開發,用了三年多了,直觀感覺的優勢以下:
node
雖然對原理也算熟,用得也算多,但一段時間不用仍是容易忘,下面記下一些平常工做場景經常使用到的命令:
場景一:如何往社區提交一個Bug
安裝git: sudo yum install git git-review
下載代碼:git clone https://github.com/openstack/neutron.gitpython
1 經過ssh-keygen命令建立密鑰, 而後在「https://review.openstack.org/#/settings/ssh-keys 界面設置public key.
2 運行「git review -s」命令設置git-review, 這步會在.git/config文件中添加一個名爲gerrit的遠程分支ssh://zhhuabj@review.openstack.org:29418/openstack/neutron.git,而且能夠經過ssh訪問:ssh -p 29418 review.openstack.org)
若是報「Permission denied (publickey)」這樣的錯的話,簡單運行"ssh-add"命令將ssh key添加到ssh agent便可
3 若是想要修改一個bug時,先建立一個本地分支,
git checkout -b task/132002
4 寫完代碼以後,也得運行一下pep8測試吧
pep8 --count --repeat --show-source . 或者 ./run_tests.sh -p -N
5 或者也運行一下單元測試吧
nosetests -s -v test_backend_sql.py && nosetests -s -v test_db_plugin:TestNetworksV2.test_list_shared_networks_with_non_admin_user
或者 python -m testtools.run neutron.tests.unit.test_security_groups_rpc
或者 python setup.py testr --slowest --testr-args='--subunit neutron.tests.unit.test_security_groups_rpc' | subunit2pyunit
或者 ./run_test.sh -N testtools.run neutron.tests.unit.test_security_groups_rpc
6 提交代碼到本地庫
git add -u (修改的文件), 若建立了新文件 git add -i
git commit
提交信息的格式通常以下,通常分三段,第一段是標準說清楚你要作什麼,若是你在改hyper-v模塊最好有hyper-v的字眼,這樣你們在收到郵件時只看標題就知道你在作什麼了,這很重要;第二段簡短描述;第三段通常使用「Fixed bug #161317",#號很重要,這樣會自動在gerrit上連接到bug上。
Add documentation for upgrading hyperv OpenStack compute node
This guide covers how to upgrade and configure hyperv OpenStack
compute node from Grizzly to Havana
Fixed bug #161317
若是是延用上次提交的信息使用命令:git commit --amend
7 原本在git review經過後gerrit會自動rebase到master分支的,可是有衝突的話沒人幫你改,因此本身在git review前最好在本地作一個rebase操做,有衝突及時改:
git rebase master 有衝突再解決衝突以後繼續執行:git rebase --continue
8 提交代碼評審
git review 或者 git review masterlinux
這時會在gerrit服務器上建立一個本地分支:refs/for/master/task/132002, 若是上面改bug時不建分支的話,這裏就變成了: refs/for/master,下一我的提交直接就被沖掉了。git
9 若是社區上的jenkins出錯,肯定不是你本身的代碼形成的,能夠回覆「recheck no bug」 觸發從新檢查,或者"recheck bug ###"github
10 說說依賴提交,例如若是一個patch在社區已經被不少人+1了,但這時候有人但願提交一個相關的其餘patch, 你固然不想破壞這麼多已經+1的成果,因此你會但願再提一個patch但它會依賴前一個patch。注意兩點:生成一個新的gerrit評審頁是由Change-Id決定的;而是否在一個評審頁上產生一個新的change set去破壞+1是由commit id決定的。因此只要保證前一個patch的commit id不變就好了,而後在這個基礎上再提交一個patch再git review便可。固然,在git review以前最好先git rebase一下,否則若是本地git rebase的話就會產生一個新的commit id這樣一樣會產生一個新的change set,不過gerrit還比較智能,那些+1會自動添加上(Automatically re-added by Gerrit trivial rebase detection script.), 一個例子見:https://review.openstack.org/#/c/51375/
場景二:如何rebase代碼
git rebase用於在一個分支中合併另外一分支,舉個例子,一家公司想要用OpenStack作二次開發的話,
在公司內部的git庫裏建立了三個分支:my-master, my-grizzly, my-havana
OpenStack的git庫裏的分支叫: github-master, github-grizzly, github-havana
如今你們把內部代碼都提交在my-havana分支,那麼也須要時不時將社區的github-havana的代碼rebase合併到my-havana分支中
1,首先在.git/config裏要有兩個remote分支,一個指向內部的版本庫,一個指向github的版本庫,如.git/config的相應配置以下:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "my-origin"]
fetch = +refs/heads/*:refs/remotes/my-origin/*
url = git://<your_ip>/neutron.git
[remote "github-origin"]
fetch = +refs/heads/*:refs/remotes/github-origin/*
url = https://github.com/openstack/neutron.git
[branch "master"]
remote = my-origin
merge = refs/heads/master
[branch "my-havana"]
remote = my-origin
merge = refs/heads/my-havana
[branch "my-grizzly"]
remote = my-origin
merge = refs/heads/my-grizzly
2, 更新上面全部的remote分支 git remote update
3, 由於是要將社區的havana分支的代碼同步到本身havana分支,因此爲兩個遠程分支建立對應的本地分支
git checkout -b github-havana github/stable/havana
git checkout -b my-havana origin/my-havana
4, 合併,成功後應該用git log -1能看到一個新的合併提交。若是有衝突的話就解決衝突再git merge next
git checkout my-havana
git merget github-havana
5, 運行單元測試
tox --recreate -e py27,pep8
./run_tests.sh -V -f
6, 用-n參數(dry-run)測試提交, 提交到名爲my-origin的遠程分支的my-havana分支中:
git push -n my-origin HEAD:refs/heads/my-havana
若沒有問題的話真正提交:
git push my-origin HEAD:refs/heads/my-havana
場景三:cherry pick代碼
例如,一個社區bug 1161195被提交到master分支, 社區沒有批准進stable-havana分支,或者來不及等它進,這時候公司內部要求進my-havana分支的話,能夠將這個bug經過cherry pick合併過來。
1, 爲這個任務建立一個bug.
git checkout stable-havana
git pull
git checkout -b bug/1161195
2, 在社區找到bug 1161195的代碼提交id, 如:5f3fa391ed499750ad68ad5b000b4e2e0a86978e
能夠經過 git log |grep -B 30 <commit-id>查看確認
3, 在bug/1161195分支上執行cherry pick命令:
git cherry-pick -x <commit-id>
4, 提交代碼評審
git commit or git commit --amend
git review stable-havana
算法
場景四:將git產生的patch變成和svn兼容sql
#!/bin/sh
#
# git-svn-diff
# Generate an SVN-compatible diff against the tip of the tracking branch
REV=`git svn find-rev $(git rev-list --date-order --max-count=1 master)`
git diff --no-prefix $(git rev-list --date-order --max-count=1 master) $* |sed -e "s/^+++ .*/& (working copy)/" \
-e "s/^--- .*/& (revision $REV)/" \
-e "s/^diff --git [^[:space:]]*/Index:/" -e "s/^index.*/===================================================================/"
shell
在本機上建立一個共享的git庫:
ubuntu
sudo groupadd git
sudo useradd -d /home/git -m -g git git
sudo passwd git
su - git
mkdir /home/git/patent.git
cd patent.git/
git init --bare --shared
# test in another directory
cd /bak/tmp
git clone git@9.123.136.122:/home/git/patent.git
cd patent
cp test.doc .
git add test.doc
git commit -m "init commit"
git push origin masterbash
這時候確定是但願你們經過git用戶能夠訪問git庫,但又不但願他們經過ssh登陸這臺機器,因此修改/etc/passwd文件,
將 「 git:x:502:503::/home/git:/bin/bash 」
改爲:git:x:502:503::/home/git:/usr/bin/git-shell
這時候還須要將每一個客戶端的公鑰加到/home/git/.ssh/authorized_keys文件裏,公鑰能夠經過ssh-keygen -t rsa生成。
場景五,使用git命令操做bzr與hg
sudo apt-get install mercurial python-hglib
wget https://raw.githubusercontent.com/felipec/git-remote-hg/master/git-remote-hg
wget https://raw.githubusercontent.com/felipec/git-remote-bzr/master/git-remote-bzr
sudo chmod 755 ./git-remote-*
sudo mv git-remote-* /usr/bin
examples:
git clone "bzr::lp:ubuntu/ifupdown"
git clone "bzr::lp:debian/ifupdown"
git clone "hg::http://anonscm.debian.org/hg/collab-maint/ifupdown/"
場景六,依賴提交
有一種狀況,我向社區同時提交了兩個有依賴的提交,在本地提交這兩個提交以後直接git review便可。
如今前一個提交(假設提交id爲:187f)要修改,怎麼辦呢?
a, git rebase 187f^ --interactive, 回到要修改的提交的前一個點上
b, 修改那個提交,最後git commit --amend
c, git rebase --continue, 繼續變基而且返回到原來的HEAD處
若是中間出現「interactive rebase already started」, 用「git rebase -i --abort」命令重來。
其它命令:
git reset HEAD~1 撤銷最後一次提交。
git reset --hard HEAD^ 撤銷最後一次提交併清除本地修改
git reset --hard Merge_Head 和服務器保持一致
git clean -dfx 刪除本地未在版本庫的東西
git stash & git stash list & git stash pop 暫存代碼
git rebase -i --abort