涉及到的基本操作
- 登錄 gerrit
- 激活郵箱
- 獲取 http Credentials
- 拉取代碼
- 提交代碼
- Review & Verify & Submit
初次使用
登錄 gerrit -> 激活郵箱 -> 獲取并保存 http credentials(提交時(shí)要用)
激活郵箱
后續(xù) Push, Review, Verify, Submit, 接收通知 等都需要郵箱的支持。
- 登錄 -> 進(jìn)入 Settings -> Email Addresses;
- 輸入郵箱地址 xxx@xxx.com, Click “Send VERIFICATION” button 發(fā)送驗(yàn)證郵件;
- 接收郵件 訪問(wèn) 驗(yàn)證鏈接;
- done.
獲取 Http credentials
http 方式 Pull, Push 時(shí)用。
- 登錄 gerrit -> 進(jìn)入 Settings -> HTTP Credentials;
- 點(diǎn)擊 "GENERATE NEW PASSWORD" Button 獲取 password;
-
done.
gerrit_http_credentials.png
開(kāi)發(fā)
Pull -> Commit -> Push(帶上Change-Id)
拉取代碼
BROWSE -> Repositories。
倉(cāng)庫(kù)地址在倉(cāng)庫(kù)詳情頁(yè)。
Attention
Pull 時(shí)選擇 "Clone with commit-msg hook" 方式以便 拿到 commit-msg (.git/hooks/commit-msg) 。
- Http 方式;
- ssh 方式;
提交代碼
確保 commit footer 有 Change-Id 信息。
Change-Id 可從通過(guò) commit-msg (.git/hooks/commit-msg) 生成。
Strongly recommended:
只需確保項(xiàng)目目錄(.git/hooks/)下有 commit-msg 腳本,再配合對(duì)應(yīng) 的 gerrit 插件即可在 Commit 時(shí)完成 Change-Id 的自動(dòng)生成。
Idea, Eclipse 都有相應(yīng)的 gerrit 插件。
Change-Id
用于標(biāo)識(shí) commit。
Have a look
Parent: 65c50d48 (Update Dockerfile base image to 0.1.2)
Author: xxxx <xxxxx@qq.com>
AuthorDate: 2019-12-12 17:41:51 +0800
Commit: xxxx <xxxxx@qq.com>
CommitDate: 2019-12-12 17:41:51 +0800
add readme.md;
Change-Id: Iba58fbc6a1a440a9d3e2e48bbd72f898ba3cabc0
Review
Review & Verify & Submit
YOUR -> Changes -> 選擇對(duì)應(yīng)的 Change -> REPLY;
添加接收者,抄送者,評(píng)論,并對(duì) Code-Review, Verified(若有權(quán)限) 打分。
若 Code-Review Verified 對(duì)應(yīng)的分?jǐn)?shù)均符合 Sumbmit 要求,
則 當(dāng)前Change 狀態(tài)變?yōu)?Ready to submit, 放出 Sumbim 按鈕。點(diǎn)擊 Submit 按鈕 完成 變更往 gerrit 倉(cāng)庫(kù) master 分支的提交。
Git 知識(shí)準(zhǔn)備
對(duì)于一些進(jìn)階操作或部分問(wèn)題的處理,要求對(duì) git 有一定的程度的深入了解。
rebase & merge
rebase(變基), merge
- 共同點(diǎn):都有整合代碼的功能
- 異同:merge操作會(huì)生成一個(gè)新的節(jié)點(diǎn)(commit)來(lái)承載這次整合,之前的提交分開(kāi)顯示。而rebase操作不會(huì)生成新的節(jié)點(diǎn)(整合在原有的commit 上完成),是將兩個(gè)分支融合成一個(gè)線性的提交。
git commit --amend
對(duì)前一次 commit 進(jìn)行微調(diào)(打補(bǔ)丁),不產(chǎn)生新的 Commit。
git commit –amend [options]
fetch vs pull
可簡(jiǎn)單理解為: pull = fetch + merge
git reset
-
reset --soft
Does not touch the index file or the working tree at all (but resets the head to <commit>, just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it.
重置 HEAD 和 branch 時(shí),保留工作目錄和暫存區(qū)中的內(nèi)容,并把重置 HEAD 所帶來(lái)的新的差異放進(jìn)暫存區(qū)。
-
reset --mixed
Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action.
reset 默認(rèn)參數(shù) mixed。重置 HEAD 和branch的同時(shí),保留工作目錄,并且清空暫存區(qū),并把重置 HEAD 所帶來(lái)的新的差異放在工作目錄。
-
reset --hard
Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded.
重置 HEAD 和branch的同時(shí),重置stage區(qū)和工作目錄里的內(nèi)容
參考文檔 git reset
Caution
- 應(yīng)總是確保 Commit 有對(duì)應(yīng)的 Change-Id
- 盡量采用 rebase 方式合并代碼, 而非 merge 方式
Problems
一些常見(jiàn)的問(wèn)題及對(duì)應(yīng)的解決方案。
初次使用 Push 時(shí)遇到 鑒權(quán)失敗
- 首先應(yīng)確保 gerrit 賬戶名無(wú)誤;
- 檢查 Push 密碼 是否為 Http Credentials;
初次使用 Push 時(shí)遇到 remote rejected
此種情況多是由于 本地 git 配置 name, email 與 gerrit 賬戶名, 注冊(cè)郵箱不符。
解決方案:查看并修改 git 配置屬性 name, email
# 查看 git 配置
git config --list
# 修改 name 屬性
git config -- global user.name '<gerrit_user_name>'
# 修改 email 屬性
git config -- global user.email '<gerrit_registered_email>'
# 兩次檢查 git 配置... done.
git config --list
ref update failed: REJECTED_OTHER_REASON no new changes
問(wèn)題分析
這個(gè)提示表示沒(méi)有新的提交。Gerrit審核根據(jù)commit
id和changeId來(lái)判斷是否是新的提交。
情況一:如果確實(shí)需要提交,比如在初次建立新的分支的時(shí)候,兩個(gè)分支的內(nèi)容完全一模一樣
解決辦法:
通過(guò)git commit –amend生成新的changeId。
情況二: 合并時(shí),合并的那些歷史的 commit 節(jié)點(diǎn),在 gerrit 上都已經(jīng)評(píng)審過(guò)了,都是已有的 change 單,所以 gerrit 認(rèn)為沒(méi)有新的提交,就不讓你提交評(píng)審。
解決辦法:
在 git merge 的時(shí)候,加上 --no-ff 參數(shù),是為了讓它生成一個(gè)新的 commit,這樣就可以提交了~(不過(guò)生成的 gerrit change 是看不到改動(dòng)信息的
結(jié)合 Idea gerrit 插件的使用:
- 合并時(shí)勾選 "No fast forward" 選項(xiàng);
- Push 時(shí),不勾選 "Push to Gerrit" 選項(xiàng);
because ref update failed: REJECTED_OTHER_REASON commit ff9671c: missing Change-Id in message footer
解決辦法:
- 通過(guò)git commit –amend 生成新的changeId (推薦);
- reset 到上一次 Commit, 生成新的changeId,重新提交;
One or more refs/for/ names blocks change upload The remote end hung up unexpectedly
問(wèn)題描述:相應(yīng)分支掛起(可簡(jiǎn)單理解為分支狀態(tài)異常)
解決方案:
在對(duì)應(yīng)倉(cāng)庫(kù)下執(zhí)行以下命令
git for-each-ref refs/for
# 如果第一條命令執(zhí)行完后有輸出,再執(zhí)行下面的命令。
for n in $(git for-each-ref --format='%(refname)' refs/for);do git update-ref -d $n; done
! [remote rejected] master -> refs/for/master (you are not allowed to upload merges)
git stash
# 每次 push 前通過(guò) rebase 方式拉代碼
git pull --rebase
git push
git stash pop
Gerrit 提示沖突,不能合并代碼(git解決遠(yuǎn)程沖突)
- 將存在沖突的 Change Abandon(丟棄)
- 在本地處理好沖突(rebase/merge)再提交
以下是 rebase 方式(推薦)
## rebase 方式
git branch #查看分支情況
git checkout master #選擇分支
git fetch origin #fetch與pull的區(qū)別,自己再搜吧~
git rebase origin/master #查看有“CONFLICT (content): ”的地方,手工解決沖突后,下一步
git add dev/controller/web/index.php #這只是一個(gè)舉例,即要先add操作
git rebase --continue
git push origin HEAD:refs/for/master #OK了
項(xiàng)目管理
遷移舊項(xiàng)目
以 gitlab 為例。
以管理員身份登錄 gerrit -> 創(chuàng)建項(xiàng)目倉(cāng)庫(kù) repo_demo -> 進(jìn)入 gerrit_home/<git_dir> 以 gitlab 中同名項(xiàng)目覆蓋之(即刪除 repo_demo
-> 再?gòu)?gitlab 克隆同名項(xiàng)目)
# 刪除 repo_demo
rm -rf repo_demo
# 從 git 倉(cāng)庫(kù)全量克隆同名項(xiàng)目
git clone --mirror <repo_url>
# 若 gitlab 倉(cāng)庫(kù)代碼有更新則 再全量拉取一次 即可
git fetch --all