Gerrit 中使用的常见用法及常见问题记录(更新中)
Posted 小羊子说
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gerrit 中使用的常见用法及常见问题记录(更新中)相关的知识,希望对你有一定的参考价值。
文章目录
1. 环境准备: Repo+Git+Gerrit
-
代码管理工具 repo ,Google的代码管理工具
-
Git 代码同步工具
-
Gerrit 代码CodeReview工具
2. 开发中
2.1 代码更新:
由于repo的配置是默认更新所有项目的master分支,用repo sync
更新前记得将当前的分支进行切换。如切换到master
分支,切换时如果有代码需要缓存,先缓存。
更新步骤如下:
- 工作区代码先缓存:
git stash save “xxx”
(代码对应还原 git stash pop)
- 如果是整个仓库更新,先将功能开发的
fiture-xx
切换分支 到master
:
git checkout master
之后再更新:
repo sync
最后切换到之前的分支,再还原代码。
git checkout fiture-xx
git stash pop
- 如果只更新当前的功能开发分支
fiture-xx
,则执行:
git pull --rebase
同样地,更新前先缓存工作区代码。
2.2 代码提交
2.2.1 添加到暂存区
看个人习惯,命令中用:
git add .
注意提交所有的未同步的文件 ,包括新增的和修改的。 注意不要提交不相关的文件。需要仔细检查。
如果用android studio,则 cmd+K(macOS系统),选则相应的文件提交。
2.2.2 添加提交说明
git commit -m “提交说明”
2.2.3 生成commit-id
事先配置好提交的ip.
gitdir=$(git rev-parse --git-dir); scp -p -P 80 tusi@ip:hooks/commit-msg $gitdir/hooks/
git commit --amend
2.2.4 推送到gerrit
在git bash执行命令:git push origin HEAD:refs/for/远程分支名
最后会在gerrit中查看、jenkins构建,添加add reviewers进行相关人员来code review等操作。
之后就准备修改、解决冲突等。
3. git使用好习惯实践
git status检查仓库状态
一个很好的习惯,add
, commit
, push
等操作前后都可以用git status
检查下,有助于理解Git
的原理
git status
熟练用命令提交、保存、切换分支 等,解决总结各种问题并记录下来。
4. 常见命令小结
git log 查看提交历史
git show HEAD git show HEAD查看父母的消息
git reset --soft HEAD^ 和git commit -a合并提交
区别:
git reset –-soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可;
git reset -–hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,撤销的commit中所包含的更改被冲掉
git commit -a
-a参数可以将所有已跟踪文件中的执行修改或删除操作的文件都提交到本地仓库,即使它们没有经过git add添加到暂存区,注意.
(git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤。)
git pull --rebase 消除同一分支的合并记录,保持提交信息清爽,每次更新时必要操作。
git pull --rebase, --rebase 可以简写为 -r
使用 git rebase 代替 git merge 执行 pull 操作。git pull --rebase 可以构造出非常整齐的提交历史树,强迫症的福利。git 的官方文档一再提醒这是个危险操作,因为它会修改你的代码提交历史。git rebase 的本质是撤销指定的提交,然后以指定的方式重新提交他们。git pull -r 就相当于首先撤销没有推送到远端的 commit,将远程代码覆盖到本地之后,重新提交所有之前撤销的 commit。与 git merge 不同,当有冲突产生时,git rebase 不会为你的 merge 操作生成一个新的提交。所以一旦 git pull --rebase 执行完毕就无法撤销。
$ git branch #查看本地分支
$ git branch -r #查看远程分支
$ git branch -a #查看所有分支
$ git branch -vv #查看本地分支关联的远程分支
$ git branch br_name #创建本地分支
$ git branch -d br_name #删除本地分支
$ git push --delete origin br_name #删除远程分支
$ git checkout -b branch_name origin/br_name #创建对应远程分支的本地分支
$ git branch -m old_branch new_branch #重命名分支
5. 项目中的使用示例
首次提交流程:
-
提交日志commit (cmd+K) 这里可以用IDE来提交。后面的流程用命令。
正常操作即可。
-
hook操作
gitdir=$(git rev-parse --git-dir); scp -p -P 29418 june@ip:hooks/commit-msg $gitdir/hooks/
注意:示例中的june@ip需要配置好自己的。
3. 再次提交
git commit --amend
-
进入Vim操作中,添加日志 保存退出
:wq
. -
push 添加wip状态意味着 当次提交不会合并,在编辑中。
git push origin HEAD:refs/for/分支名%wip
git push origin HEAD:refs/for/分支名
注意 其他项目中的提交需要单独提交。防止提交遗漏。
第二轮修改后提交流程:
- 如果没有通过被拒绝之后,修改后再次提交
git add .
git commit --amend
如果在IDE中使用commint --amend中的方法 会出现 日志修改无效的问题。
其他场景
- 不小心在commit时提交不该提交的文件。
git log -n 1 --stat
git reset --soft HEAD^
回到最近1次的提交,执行完成后 你会发现,commit取消了,代码又回到缓存区了。
6. Vim操作
git中的用命令操作,Vim的相关用法必不可少,我们也得熟练运用。
vim 有两种工作模式:
1.命令模式:接受、执行 vim
操作命令的模式,打开文件后的默认模式;
2.编辑模式:对打开的文件内容进行 增、删、改 操作的模式;
3.在编辑模式下按下ESC
键,回退到命令模式;在命令模式下按i,进入编辑模式。
常用的用法:
保存文件退出
:w 写入不退出
:w! 强制写入
:wq 写入退出
:wq!写入强制退出
ZZ 写入退出,使用shift+两次ZZ
:q 退出
:q!强制退出
小结:
'i’进入编辑模式
'esc’进入命令模式
':wq’保存退出
'q!'不保存强制退出
异常总结:
1.Git中vim修改权限: E45: 已设定选项 ‘readonly’ (请加 ! 强制执行)
初始设置进行修改操作后,无法保存,git命令行输入指令:
:wq!
回车即可强制修改并保存。
- Changed_ID 必须放到下面 否则会push失败。
使用心得:git commit --amend 时 会进入vim界面,
-
如果只是查看不做任何操作,直接输入“:q”即可退出,不要做任何多余的操作。
-
如果想在提交信息中添加,直接输入“i”,左下角会出现“插入”提示,此时需要内容,输入完成后退出命令模式时,按“ESC‘,
此时进入等待编辑模式,如果此时不做任何操作,想要退出时输入”:q“ 如果有提示强制退出,输入”:q!“ 或根据提示输入“:wq”.
小结: 插入时按”i“,退出时按”ESC“,此时需要再次插入 又按”i“,再退出按”ESC“.
7. FAQ
- Git 还原到指定的版本
首先找到你想要回退的版本,在命令行中执行:
git log --oneline
上述命令执行后会看到 Git 提交的历史记录列表。
在列表中找到要回退的版本,复制它的提交 SHA,然后执行下述命令回滚到该版本:
git checkout 175070c . (示例,注意结尾的点)
之后你会看到代码被还原成当前的提交信息,代码被修改了。
接下来,你可以正常提交如:
git add .
git commit -m “desc”
git push xxx
- 回退提交
在git bash 执行命令:git reset –soft HEAD~n(有几次提交n就为几)
- 问题:推送到gerrit上的change出现can not merge
这种情况出现的原有两个:
1.提交的代码与远程别人的提交(已经合入远程仓库)有冲突。
2.修改的基础落后于远程仓库中的代码,没有更新到最新。
解决方法
- 此时先点击页面上的rebase按钮,并且在弹出的框里勾选change parent revison。
- 点击rebase。表示先rebase远程最新的代码更新。
若此时仍然出现Cannot merge,则表示有冲突,解决方法如下:
- 同步远程最新的代码,在git bash中执行命令:git pull –rebase
- 在所有冲突的文件中,解决冲突。(请仔细看命令行的提示)
- 重新提交代码,并保证与原始Change-Id一致: 在git bash 中执行命令: git commit –amend
- 在出现的文本编辑器中,修改提交信息。(若不需要修改就直接保存按:q退出)
- 再次推送到gerrit: git push origin HEAD:refs/for/远程分支名
另一种解决办法:
cd ~/projects/pan #切换到pan项目
git branch #查看分支情况
git checkout master #选择分支
git fetch origin #fetch与pull的区别,自己再搜吧~
git rebase origin/master #查看有“CONFLICT (content): ”的地方,手工解决冲突后,下一步
git add dev/controller/web/index.php #这只是一个举例,即要先add操作
git rebase --continue
git push origin HEAD:refs/for/master #OK了
git push后,你需要在Gerrit里面再次review一次。
- git commit 后想回退
// 不小心commit了1次
git reset --soft HEAD^
// 不小心commit了2次
git reset --soft HEAD~2
- missing Change-Id in commit message footer
先执行这两条命令,命令中的信息改成自己的.
gitdir=$(git rev-parse --git-dir); scp -p -P 80 tusi@ip:hooks/commit-msg $gitdir/hooks/
git commit --amend
之后,再次push
.
- Gerrit merge conflict
- 在
Gerrit
上abandon
这次push
- 软回滚
git reset --soft origin/master
pull
代码
git pull --rebase
再次commit
, push
- gerrit 的 Change-Id 机制:
首先要明确, Change-Id 是 gerrit (代码审核平台)的概念, 与 git (版本管理) 是没有关系的.
简单来说, Change-Id 是 gerrit 用以追踪具体提交的机制. 这里不贴网上已有的解释,举两个栗子大家体会下:
-
你已经用 git push 将代码提交 gerrit 审核了,这时你发现代码中有疏漏,修改了一下,执行 git commit --amend, 再次推送还可以成功. 这就是因为 gerrit 检查到两次 push 的 commit 有同一个 change-id, 就认为是同一个提交,因此可以 amend.
-
git push 将代码提交到 gerrit 审核,到 gerrit 网站一看,大红字标着 Can Not Merge 字样. 我想常用 gerrit 的同学肯定都遇到过这问题. 之前我的做法是, git reset 后,更新代码,再重新提交. 现在的做法是,不用 git reset 了,直接 git commit --amend, 删掉 commit log 中的 change-id 那行,然后wq保存退出.这时 gerrit 的那个钩子脚本会再生成一个不同的 change-id ,这时再更新代码,重新提交即可成功. 这里只简要介绍该方法,具体步骤将在 代码冲突 场景中详解.
-
在Mac代码提交时出现了
.DS_Store
文件。(2021.3.5新增)
解决办法:
-
删除当前目录及其子目录下的所有.DS_Store 文件
find . -name “*.DS_Store” -type f -delete
-
添加到.gitignore 文件
如果你的项目中还没有自动生成的 .DS_Store 文件,那么直接将 .DS_Store 加入到 .gitignore 文件就可以了。如果你的项目中已经存在 .DS_Store 文件,那就需要先从项目中将其删除,再将它加入到 .gitignore
删除项目中的所有.DS_Store。这会跳过不在项目中的 .DS_Store
1.find . -name .DS_Store -print0 | xargs -0 git rm -f --ignore-unmatch
将 .DS_Store 加入到 .gitignore
2.echo .DS_Store >> ~/.gitignore
更新项目
3.git add --all
4.git commit -m '.DS_Store banished!’
- 终极解决办法
禁止.DS_store生成:
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool TRUE
恢复.DS_store生成:恢复.DS_store生成:
defaults delete com.apple.desktopservices DSDontWriteNetworkStores
-
关于Change-id的缺失处理
-https://blog.csdn.net/weixin_30542079/article/details/96107170
https://luomuxiaoxiao.com/?p=337 -
关于用分支缓存代码的问题 (2022.3.25 新增)
其他开发同学 A 有一笔未入库,只是提交了代码,用于 cherry-pick 如果你用了 cherry-pick ,并做了缓存。那么,代码的基准点会变为上一笔未入库的代码。这笔代码在gerrit中 code Review 之后,是不能入库的,必须等 A 的代码入库(如果你的代码和他有关联)。
解决办法:先缓存当前的代码 git stash save “demo”
再切换分支( git checkout -b dev(你想要缓存的分支) ),用本地分支来缓存当前的代码提交,然后 git reset --hard commit-id(你要提交的最新基准线id)
之后 git stash pop 再 git add.再git commit 和git push 始可。
最后放一张常用的 git 命令,随时熟悉一下:
参考:
Gerrit常见问题解决
Git: 如何修复gerrit merge conflict状态
Gerrit status Merge conflict 解决
git 合并两个提交 - git reset --soft HEAD^
Git 以及 Vim 常见命令整理(可了解一下如何合并多个提交记录到一个记录)
如何删除mac中的.DS_Store和git中的.DS_Store
以上是关于Gerrit 中使用的常见用法及常见问题记录(更新中)的主要内容,如果未能解决你的问题,请参考以下文章