iCode常见问题

git push HEAD:refs/for/master,长命令输入较麻烦,是否有更便捷办法?

push时不能支持直接push到icode分支。必须执行下面命令发评审。

git push origin <当前分支>:refs/for/master

如何简化命令?

可采取如下方法,该方法与git-completion.bash兼容,实现tab自动补全
执行下面的配置,安装一个gpush子命令

git config --global alias.gpush '!f() { : push ; r=$1; [[ -z $r ]] && r=origin; b=$2; t=$(awk "{ print \$2 }" $(git rev-parse --git-dir)/HEAD); t=${t#refs/heads/}; [[ -z $b ]] && b=$t; cmd="git push $r HEAD:refs/for/$b%topic=$t"; echo $cmd; echo; $cmd; }; f'

执行

git gpush

会自动转为

git push origin <当前分支>:refs/for/<当前分支>

执行

git gpush origin master

会自动转为

git push origin <当前分支>:refs/for/master

git push origin master:ref/for/master失败

命令输入错误(少输入了s),正确命令为refs/for/master。如果是ref/for/master则代表创建上述远程分支,而不是发评审。

git push了中文分支名,出现报错

使用中文会导致系统异常报错,请使用英文分支名。

提交评审被hook,提示Git account Configuration is error.

如果按此帮助操作仍无法成功,请准备两部分截图信息并咨询客服人员。

第一部分:执行下方命令并对结果截图

git log origin/[分支名]..[分支名] --oneline --graph --format="%H,%ce"

第二部分:按照下面解决步骤执行并截图(否则客服会因为缺少诊断依据而无法提供人工支持)

解决步骤:

首先确定要push的所有commit,以及这些commit对应committer的邮箱(icode会对本地commit的committer和icode账号进行一致性校验)。

例如,push本地master到远程origin/master分支,可以用如下命令查看:

git log origin/master..master --oneline --graph --format="%H,%ce"

情况1:结果中最新一笔commit的committer邮箱不是你的邮箱,可以用以下方式解决:

1.设置公司帐号邮箱,使用git config -e命令,将下图[user]标签下的name和email设置正确(如未设置请照下图格式设置[user]标签和name,email)。

1.png

2.更新git commit里面的帐号信息(执行下面命令无需修改commit信息,直接保存退出即可)

git commit --amend --reset-author

3.重新push

情况2:结果中非最新一笔commit的committer邮箱不是你的邮箱

解决方法:使用git rebase命令对非最新的commit进行修改

参考相关信息:
https://gist.github.com/trey/9588090
https://backlog.com/git-tutorial/cn/stepup/stepup7_6.html

情况3:需要同步第三方代码

先push到一个不存在的分支,例如:git push origin HEAD:third_patry_branch,再合并到现有分支(提交历史会多出一笔merge commit,无其他影响)

Git push origin HEAD:refs/for/(分支) 报错

直接原因是git push时发现没有新的改动可以push。导致问题的场景可能有以下几种:

【场景一】

已有一个master和一个dev
远端master和本地master进行了更新
本地checkout dev
merge master --> fast fowrad
然后向dev发评审 --> 报 no new changes
因为你merge的节点在icode已经合入

解决方案:不要在本地merge代码,去iCode对比页合并。

【场景二】

例如,最开始同时push了三个commit,按照changeid排序是这样的:1<-2<-3
在第三个commit有问题的时候,本地reset到第二个commit,再执行一下push,就会报no change

【场景三】

执行git log --pretty=oneline --decorate --graph 可以看到我的历史是这样的,我现在是基于master工作的
2.png
无法通过执行it push origin master:refs/for/force,将基于master的更改提交到orgin/force。
因为远端的master和force分支的历史不是一个节点,相差很多版本。
3.png

解决方法:

git checkout origin/force
git checkout -b force
git cherry-pick e45898ca2fb11f8e258a7067fbba9f6a44ba6dba (提交到maste上的commit拣选到force分支)

【场景四】

打tag的正常流程:先本地commit,发评审合入后再打tag。也会有在本地commit,打tag后直接push tag的情况。对于这些情况,icode在流程上并没有做限制。但是icode对比页面合并时,不支持合并tag,原因是若开放按标签名合并会造成可以跳过评审的漏洞。因此合并tag到分支时需在本地操作:git checkout 【要合并的分支名】; git merge --no-ff 【tag名】(此处一定要加--no-ff,否则会报no new change); git push origin HEAD:refs/for/【要合并的分支名】;至此可以发起一笔merge tag的评审做合并。

push时报错“Sorry, you were trying to upload xxx commits in one push”怎么解决?

情况1:

报错原因:因为代码库>[提交规则]中设置了[仅含一个commit],这样的话一个评审中只能带一个commit,当需要对评审中的代码追加patch时再持续commit生成多次提交就会报此问题。
4.png

解决方法:

  1. 本地更改完代码并add后,使用git commit --amend提交新修改的代码(注意不要在此命令中想当然的加上-m参数),千万不要继续使用git commit -m "some comments"来提交。这样可以避免一个功能在本地生成多个commits。
  2. 如果需要在本地合并其他分支的代码,使用git merge 或git pull自然会生成一个全新的merge commit,这样就不能保证只有一个commit了。故遇到此情况,换用git rebase [别人的分支]或git pull --rebase ,用rebase的方式来解决即可。

注意:不要使用git reset --soft回滚代码后重新提交,此法会导致iCode上生成多个无用的评审单,会给你和评审人带来不必要的麻烦。

情况2

报错原因:系统限定单个评审的最大commits个数不能超过100

解决方法1:
如果你是导入他人代码(例如:开源代码),无需评审,那么请首先将这些代码push到一个不存在的分支上,再合并到目标分支。举例:
$ git push origin HEAD:[不存在分支名]
去icode对比页,找到两条分支,执行合并,如下图:
5.png

解决方法2:(不推荐该方法)

如果可以放弃他人的提交历史,那么可以直接使用reset命令将所有提交合并为1个

$ git fetch
$ git reset --soft origin/[你的分支]
$ git add .
$ git commit -m "some comments"

再重新发评审,就不会被拦住了。

错误:Permission denied. Creating new branch is only allowed for members of this repository

这个错误一般在push新分支的时候会出现,原因是权限不足。(只有代码库的管理员和具备写权限的角色可以push新的分支)

提交不能包含merge节点

一次push的commit节点中不能包含merge的节点,例如
6.png

解决方法:
git reset 833011(merge节点之前的commitid)
然后重新git add ,git commit ,git push

报错:Push failed, because you are not a member of this repo

原因:对于“公开”类型的代码库,只有代码库的管理员、写成员、读成员,具备使用push命令发评审的权限。对于其他非成员用户,只能只读代码库(即clone 和 pull)。

解决方法:

  1. 联系此代码库的管理员,给你添加相应的权限,例如:读成员
  2. 联系此代码库的管理员,将代码库的类型由“公开”修改为“开源”,这里的是指企业内部的开源。对于开源的代码库,允许非成员使用push命令发评审来贡献代码。修改方法:在“代码库设置”页面,如下图选择。

为什么无法通过git push命令删除远程分支?

Permission denied. A branch can only be deleted by its creator or the administrator of this repository.

通过以下3种途径创建的git库远程分支,只有分支的创建者或代码库管理员具备删除权限:

1.icode>分支页面
2.agile>pipeline
3.git push命令行

非代码库管理员通过以下方法删除分支时,都会失败并弹出提示信息:

1.icode>分支页面;
2.git push命令

解决方案:请联系分支创建人(在“icode>代码库>分支”页面查询)或代码库管理员(在“icode>代码库>成员权限”页面查询)处理

报错:missing or invalid Change-Id line format in commit message footer

missing change id in commit message

此问题有以下三种情况:

情况1:

原因分析:克隆代码库的时候没有安装commit-msg hook导致(克隆代码库时没有选择『克隆并安装hook』)。

解决办法:
step1. 在本地代码库的根目录下先安装hook:
scp -p -P 8235 {用户名}@icode.baidu.com:hooks/commit-msg $(git rev-parse --git-dir)/hooks
step2. 执行git commit --amend,vim打开提交信息的文件,不用做任何修改直接保存退出(wq)即可。
(若依然无法push,请尝试git reset --soft origin/[branchname]后重新commit)

情况2

原因分析:已经安装hook,本地做merge操作,此时默认生成的merge commit不带change-id。
解决方法:这种情况下执行git commit --amend一下就会自动生成change-id,进而正常push了。

情况3

原因分析:
已安装hook,本地也不是做merge操作,依然报错。很可能是由于你的commit信息在编辑的时候写到了最后一行『change-id:xxxxx』的后面,push时的check会检查最后一行是否为change-id,如果夹在commit信息中间会被识别为commit信息的内容造成change-id缺失无法push。
解决方法:
使用git commit --amend修改commit message信息,一定要保证change-id在最后。

push报错:Sorry, you were trying to upload xxx commits in one push

7.png

如果超过100个commit均为自己提交的改动,建议先使用git rebase squash的方式将可以合并的commit进行合并,合并到小于100个commit再进行push。方法详见 http://zerodie.github.io/blog/2012/01/19/git-rebase-i/

如果是需要使用第三方代码,有两种情况:

情况一:使用的第三方代码无需修改

这种情况可以直接使用github mirror上的代码,无需导入iCode

  • root用户

    修改hosts文件增加一行:10.91.163.233 github.com
    请在root用户下执行 git config --system http.sslVerify false

  • 非root用户
    用户下执行 git config --global http.sslVerify false

情况二. 需要对第三方代码进行修改:

  1. 在iCode的baidu/third-party/路径下新建代码库并导入代码(直接push新分支可跳过评审), 具体操作步骤:
    Step1. 依据代码库命名规范要求的三级命名要求拟定新的代码库名,举例:baidu/icode/helloworld
    注意:保持代码库为空,在执行step2之前不要向代码库提交任何代码
    Step2. 将gitlab的代码库克隆到开发环境,添加新建的icode代码库为远程仓库,将代码推送到step1中新建的代码库中
    注意:只有被checkout到本地的分支,才会在执行git push命令时推入icode代码库中

  2. 导入第三方代码后需要增量导入commit到已有分支时,如果commit超过100个,可以先push到一个不存在的分支,例如:git push origin HEAD:third_patry_branch,再合并到现有分支。(提交历史会多出一笔merge commit,无其他影响)

Git clone命令报错unauthorized如何处理?

Unauthorized错误顾名思义,没有权限下载代码库,考虑到权限问题,需要排查以下几个方面:

  1. 该成员是否有权限下载代码库的代码,如下图所示,可读权限以上的成员可以下载代码,需在代码库权限设置页面确认该成员有代码库相应权限。

    image.png

  2. 是否按照git配置文档 进行了本机的git初始化配置。注意Git clone命令运行时使用的密码是在个人设置的部分设置的http密码。

    image.png

  3. 如果权限和配置都没有问题,且验证了某个用户在Mac,Linux下使用git
    clone命令均正常,则考虑Windows操作系统下git版本的问题。由于Icode与git的兼容性问题,推荐使用git2.3-2.10之间的版本。

每次push/pull输密码较为麻烦,是否提供工具对git http密码进行统一保存、管理?

  • Windows系统自带密码管理工具,支持对密码的记录和管理,工具名称为:Credential Manager
  • Mac系统自带密码管理工具,支持对密码的记录和管理,工具名称为:Keychain Access
  • Ubuntu(及其他有GUI的Linux)有对应的密码管理工具。
  • Linux:最通用的保存http密码的办法是写在配置文件中,如下面的例子:
$ cat >> ~/.netrc <<__END
machine xly.bce.baidu.com
login yangyang22_baidu.com_baidu
password ********
__END

machine为域名(xly.bce.baidu.com)

login/password是百度效率云-DevOps的iCode的账号和密码,查询方式见下图,注意不是登陆百度智能云账号密码,如果不知道,在个人设置中修改
image.png

代码评审完成执行“合入”操作时提示合并冲突怎么办?

原因分析:开发期间,其他同学向远程仓库推送了新代码,导致您正在开发的分支被更新,服务器自动合并时发现您二人开发的代码存在冲突。出现该情况时,需要手工解决冲突后重新评审和合入。

解决方法:

step1.回到您的开发空间,找到这个评审所在的开发目录。
(若您没有此评审的开发目录,请去iCode的评审页面按照以下步骤操作:(1)>’提交记录'(2)>’下载'(3)>复制下载命令)

step2.将远程仓库中别人更新的代码拉下来并执行合并,此时会看到冲突的提示信息

git pull

step3.查看出现冲突的文件,并修改这些冲突问题

git status

step4.添加patch set

git add .
git commit
git push origin HEAD:refs/for/[目标分支]

step5.回到iCode评审页面,重新打分,执行“合入”即可

缺少评审人+2评分不能点“合入”按钮怎么办?

iCode默认的评审规则:机器人检查通过,且有至少一个代码库Owner给了+2分。

解决此问题有两种方法:

方法一:将最少一个代码库Owner加成评审人,联系此人人工评审,通过后给予+2分即可,如下图:

reviewer-add.png

添加评审人图1.添加评审人

review+2.png

打分图2.评审+2分

方法二:如果你是代码库的Owner,且你判断这个代码库可以不做人工评审。那么请先修改这个代码库的评审规则,入库:iCode>搜索代码库>提交规则>将“代码评审”的勾去掉,如下图:

image.png

提交规则图3.设置代码库的评审规则

特别的,若有Owner已经给了-2评审不通过,则需要按照此Owner给出的建议修改代码,发一个新的patchset(命令参考:1. 在git目录直接修改。2. git add . (或者指定文件) 3. git commit --amend 4. git push origin HEAD:refs/for/xxx),直到此Owner修改评分为+2为止。

添加评审人失败

对于保密代码库,添加的评审人可能没有member或owner权限