gerrit "missing Change-Id"

2023-11-02

场景:

你用 git push 向 gerrit 提交了待审核代码,一切都很顺利,你脑袋里冒出了"代码头上加了'佛祖保佑'果然有效"的想法.
此时 git 打印出如下提示,你的内心OS同步打印 "心情 -5" :

remote: Resolving deltas: 100% (14/14)
remote: Processing changes: refs: 1,done   
remote: ERROR: missing Change-Idincommit message footer
remote:
remote: Hint: To automatically insert Change-Id,installthe hook:
remote:   gitdir=$(git rev-parse --git-dir);scp-p -P 29418 liux@gerrit.xxxxx.com:hooks/commit-msg${gitdir}/hooks/
remote: And then amend the commit:
remote:   git commit --amend
remote:
To ssh://liux@121.xx.xx.xx:29418/kaiba_admin_yunying.git
 ! [remote rejected] HEAD -> refs/for/master(missing Change-Idincommit message footer)
error: failed to push some refs to'ssh://liux@121.xx.xx.xx:29418/sample_project.git'

套路:

大前提: commit-msg 文件必须已经在该项目中存在.

使用ls命令检查该文件是否存在:

$ cd project_dir
$ ls.git/hooks/commit-msg

如果该文件不存在,则按照 git push 时产生的提示信息,获取该文件:

$ gitdir=$(git rev-parse --git-dir);scp-p -P 29418 liux@gerrit.xxxxx.com:hooks/commit-msg${gitdir}/hooks/

上面的命令可以直接从 git push 产生的错误信息中复制出来.
如果要手敲该命令,别忘了把用户名换成自己的.

方法一: 使用 amend 选项生成 Change-Id:

如果缺失 Change-Id 的是最后一个 (head) commit, 使用以下命令即可解决问题:

$ git commit --amend

该命令会打开默认的 commit message 编辑器,一般是 vi.
这时什么都不用修改,直接保存退出即可 (:wq).
再次查看 git log,就会发现缺失的 Change-Id 已经被补上了. 再次 git push 即可.

方法二: 如果缺失 Change-Id 的不是最后一个 commit, 可用 reset 方法:

比如,如果缺失 Change-Id 的 commit 是 git log 中的第二个 commit, 则可以用 git reset 命令将本地分支回退到该 commit.
(但其实用 git reset 找回 Change-Id 是普通青年才干的事情,文艺青年有更优雅的办法.见方法三)
首先执行 git log, 找出缺失了 Change-Id 的 commit,并复制其 commit-id:

$ git log
commit 8e1cad33bcd98e175cba710b1eacfd631a5dda41
Author: liux <liux@xxxx.cn>
Date:   Mon Dec 19 17:43:00 2016 +0800
 
    testcommit"with amended commit message"
     
    Change-Id: I9d2af0cc31423cf808cd235de0ad02abf451937d
 
commit 1a9096a34322885ac101175ddcac7dab4c52665d
Author: liux <liux@xxxx.cn>
Date:   Mon Dec 19 15:23:36 2016 +0800
 
    testcommit-msg hook
 
......

发现是第二个 commit 缺失 Change-Id. 将代码 reset 到这个 commit, 并执行 amend:

$ git reset 1a9096a34322885ac101175ddcac7dab4c52665d
$ git commit --amend

注: 上面的 git reset 用法不会毁灭你写的代码,放心执行即可.
这时 git log 可以发现该 commit 已经补全了 change-Id.
下一步是把 git reset 撤消掉的代码重新 commit, 然后 push 即可:

$ git add ......
$ git commit -m "你的提交日志"
$ git push review HEAD:refs/for/master

方法三: 使用交互式 rebase 找回任意提交位置的 Change-Id:

前面方法二中给出的例子是第二个提交缺失 Change-Id,这时用 git reset 还可以解决问题.
但如果你在一个方案上已经工作了一个月,生成了100个本地 commit,提交时才发现 git log 中第99个 commit 缺失 Change-Id. 如果这时还用 git reset 来找回 Change-Id ......
不要香菇,不要蓝瘦.文艺青年表示有办法优雅的解决问题: 交互式 rebase.

第一步,找到缺失 Change-Id 的那个 commit:

$ git log
commit 8aaaa749db4a5b105aa746659c5cd266ac82fffe
Author: liux <liux@xxxx.cn>
Date:   Mon Dec 19 17:43:24 2016 +0800
 
    I am commit message 3
     
    Change-Id: Ic89d5ce6ce4de70d1dcb315ce543c86a2b3ac003
 
commit 8e1cad33bcd98e175cba710b1eacfd631a5dda41
Author: liux <liux@xxxx.cn>
Date:   Mon Dec 19 17:43:00 2016 +0800
 
    I am commit message 2
     
    Change-Id: I9d2af0cc31423cf808cd235de0ad02abf451937d
 
commit 1a9096a34322885ac101175ddcac7dab4c52665d
Author: liux <liux@xxxx.cn>
Date:   Mon Dec 19 15:23:36 2016 +0800
 
    I am commit message 1
 
commit d714bcde0c14ba4622d28952c4b2a80882b19927
Author: shangsb <shangsb@czfw.cn>
Date:   Wed Dec 14 09:20:52 2016 +0800
 
    这是一个提交
     
    Change-Id: I629b2bedff95491875f63634ad3da199612735b6
......

发现是 "I am commit message 1" 这个提交没有 Change-Id.

第二步,编辑交互式 rebase 的命令文件:

执行 git rebase -i, 参数为 该提交的上一个提交的 commit-id (本例中为 "表单" 那个提交):

$ git rebase -i d714bcde0c14ba4622d28952c4b2a80882b19927
这个命令会打开默认的编辑器,一般为 vi. 内容如下:
pick 1a9096a I am commit message 1
pick 8e1cad3 I am commit message 2
pick 8aaaa74 I am commit message 3
# Rebase d714bcd..8aaaa74 onto d714bcd
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

可以将这个文件理解为 git rebase 的内嵌脚本.其命令写法已经在下面的注释里给出了.
这里不赘述,仅给出最终要将该文件编辑成什么样子:

reword 1a9096a I am commit message 1
pick 8e1cad3 I am commit message 2
pick 8aaaa74 I am commit message 3
# Rebase d714bcd..8aaaa74 onto d714bcd
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

即: 将缺失了 Change-Id 的 commit 前面的 pick 改为 reword 即可 (简写 r 也可以). 保存退出 (:wq)
注1: 上述文件中 commit 的顺序是和 git log 显示的顺序相反的: git log 为最新的在最前; 上述文件为 最新的在最后.
注2: 如果进入该模式后,却不确定该怎么改,这时不要担心,直接退出编辑则什么都不会发生 (:q!)
注3: 如果没有搞清楚原理,就要注意,除了按需把 pick 改为 reword 外,不要做其他改动.尤其注意不要删除任何行 (被删除的那行对应的提交将丢失).
注4: 你应该已经发现,有多个 commit 缺失 Change-Id 的情况也可以用该方法一次性处理.

第三步,逐个编辑 commit-msg:

上一步打开的文件保存退出后,git会逐个打开被你标注了 reword 的提交日志页面.
不需要修改任何东西,逐个保存退出即可 (一路 :wq).

第四步,再次提交:

用 git log 查看提交日志,会发现缺失的 Change-Id 都生成了. 愉快的提交代码吧!

$ git push review HEAD:refs/for/master

心法:

gerrit 的 Change-Id 机制:

首先要明确, Change-Id 是 gerrit (代码审核平台)的概念, 与 git (版本管理) 是没有关系的.
简单来说, Change-Id 是 gerrit 用以追踪具体提交的机制. 这里不贴网上已有的解释,举两个栗子大家体会下:

  1. 你已经用 git push 将代码提交 gerrit 审核了,这时你发现代码中有疏漏,修改了一下,执行 git commit --amend, 再次推送还可以成功. 这就是因为 gerrit 检查到两次 push 的 commit 有同一个 change-id, 就认为是同一个提交,因此可以 amend.
  2. git push 将代码提交到 gerrit 审核,到 gerrit 网站一看,大红字标着 Can Not Merge 字样. 我想常用 gerrit 的同学肯定都遇到过这问题. 之前我的做法是, git reset 后,更新代码,再重新提交. 现在的做法是,不用 git reset 了,直接 git commit --amend, 删掉 commit log 中的 change-id 那行,然后wq保存退出.这时 gerrit 的那个钩子脚本会再生成一个不同的 change-id ,这时再更新代码,重新提交即可成功. 这里只简要介绍该方法,具体步骤将在 代码冲突 场景中详解.

Change-Id 的生成机制请继续向下看.

git 的 hook 机制:

钩子(hooks)是一些在$GIT-DIR/hooks目录的脚本, 在被特定的事件(certain points)触发后被调用。当git init命令被调用后, 一些非常有用的示例钩子脚本被拷到新仓库的hooks目录中; 但是在默认情况下它们是不生效的。 把这些钩子文件的".sample"文件名后缀去掉就可以使它们生效。
hook机制可以理解为回调.各个钩子其实就是一段 bash 脚本,各钩子脚本的名字都是固定的.可以查看git项目根目录下的 .git/hooks 这个文件夹,看看都有哪些可用的钩子.

$ cdproject_dir
$ ls .git/hooks/
applypatch-msg.sample  commit-msg.sample   pre-applypatch.sample  prepare-commit-msg.sample  pre-rebase.sample
commit-msg             post-update.sample  pre-commit.sample      pre-push.sample            update.sample

如果有自己感兴趣的 git 事件要处理,修改相应的钩子脚本罗辑即可.然后把 .sample 后缀去掉,钩子就生效了.
在 gerrit 的 Change-Id 生成机制中,其实 gerrit 就是利用了 commit-msg 的钩子,在我们提交代码后,按一定规则去修改了我们的提交日志,在其末尾添加了这么一行:

 Change-Id: .......

这个钩子脚本是什么时候被加入我们的项目中的呢? 其实就是你在 git push 出错时 gerrit 网站给你的提示中的那句命令:

$ gitdir=$(git rev-parse --git-dir);scp -p -P 29418 liux@gerrit.kaiba315.com:hooks/commit-msg${gitdir}/hooks/

执行该命令即可得到生成 Change-Id 的钩子脚本. 这条命令做了以下事情:

// git rev-parse --git-dir 这条命令将找到该项目的 git 目录,并将其赋值给 gitdir 这个变量.
// 一般就是项目根目录下的 .git/ 这个目录.
$ gitdir=$(git rev-parse --git-dir)
 
// 执行 scp 命令,从 gerrit 代码服务器将钩子脚本文件 commit-msg 下载到项目的钩子目录下 (一般是 .git/hooks/)
$ scp -p -P 29418 liux@gerrit.kaiba315.com:hooks/commit-msg ${gitdir}/hooks/

查看该脚本,会发现它是用 awk 命令处理了 .git/COMMIT_EDITMSG 这个文件.
所以如果想手动生成 Change-Id ,只要执行下面命令,就可以生成一个可用的 Change-Id:

$ cdproject_dir
$ echo "some commit" > /tmp/test_generate_change_id
$ .git/hooks/commit-msg/tmp/test_generate_change_id
$ cat /tmp/test_generate_change_id
some commit
 
Change-Id: Ic89d5ce6ce4de70d1dcb315ce543c86a2b3ac003

利用 git commit --amend 重新生成 Change-Id 的原理:

git commit --amend , 看名字就知道,是对某个 commit 做出修改的.这种修改既可以包含文件修改,也可以仅包含提交日志修改.
我们用 --amend 对 commit 做出修改后, commit-msg 的钩子会被重新触发, Change-Id 就会被生成出来.
用交互式 git rebase 来生成 Change-Id 也是同一个道理.
另:
通过总结历次缺失 Change-Id 的例子,发现基本我们自己通过 git commit 生成的提交都会很顺利的生成 Change-Id.
通过 git merge, git revert 等命令由 git 自己生成的 commit 则有较高概率会缺失 Change-Id.
嗯,我们发现了一个伟大的定律! 然并卵... 并不知道怎么解决这个问题.
因此提倡尽量用 git rebase 代替 git merge 来更新代码.
事实上, git rebase 更新代码 相较 git merge 更新代码,有诸多优势,只是略复杂些.强烈建议用 git rebase 方式更新代码.

git rebase -i:

呃... 自己查文档去吧, 要讲清楚这个又得写一大坨东西出来.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gerrit "missing Change-Id" 的相关文章

  • 您对版本控制进行到什么程度了? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 致命:早期 EOF 致命:索引包失败

    我用谷歌搜索并找到了很多解决方案 但没有一个适合我 我试图通过连接到 LAN 网络中的远程服务器来从一台计算机进行克隆 从另一台机器运行此命令会导致错误 但是在服务器上使用 git 192 168 8 5 运行相同的克隆命令 一切正常并且成
  • web2py git 集成 - localhost 和 pythonanywhere

    我完全不知道如何将 Github 集成到 web2py 中 我在 USB 上安装了 web2py任何地方的Python http www pythonanywhere com web2py概述文档chapter3http web2py co
  • Python 无法在 git bash 命令行中工作

    Python 不会在 git bash Windows 中运行 当我在命令行中输入 python 时 它会将我带到一个空行 而不会像在 Powershell 中一样显示它已输入 python 2 7 10 它没有给我错误消息 但 pytho
  • 由于不存在大文件而导致 git Push 错误

    当尝试推送到 git 时 我不断得到相同的结果 Counting objects 78 done Delta compression using up to 4 threads Compressing objects 100 67 67 d
  • “git add”返回“致命:外部存储库”错误

    我刚刚进入 git 的奇妙世界 我必须提交我对程序所做的一系列更改 位于名为的目录中 var www myapp 我创建了一个新目录 home mylogin gitclone 从这个目录中 我做了一个git clone针对公共回购 我能够
  • 如何使用“gem install”命令从私有 GitHub 存储库安装 gem

    如何在本地安装托管在 GitHub 上的私人存储库中的 gem 特别是 我们通过gem install命令而不是在 Bundler 中使用 因为它是一个命令行工具 我尝试这样做 gem install githubname repo s h
  • 在 GitHub 上执行拉取请求时避免不需要的合并提交和其他提交

    我在 Github 上分叉了一个项目 令远程上游为upstream我的远程存储库是origin 我当地的master分支设置为跟踪远程master分支 然后我在本地添加了一些东西master 时不时与上游汇合 直到今天我想发出pull re
  • EGit(Eclipse git 插件)可以使用 SSH 密钥代替用户名和密码吗?

    我需要提交的 git 中央存储库是使用 SSH 密钥配置的 我的用户名是jmglov 但是当我执行 git 操作时 例如git clone 我使用这个配置 jmglov kitiara cat git config remote origi
  • Git 在推送代码时返回错误 403 [重复]

    这个问题在这里已经有答案了 一切都工作正常 直到我创建了一个新的 GitHub 帐户 当我尝试使用新帐户第一次将代码推送到 github 服务器时 出现以下错误 remote Permission to NEW USER NEW REPO
  • Git 中的合并冲突是由什么构成的?

    git 如何确定特定合并存在冲突以及冲突是什么 我的猜测是这样的 如果正在合并的两个提交有一个共同的父提交 并且如果它们都更改了父提交的 X 行 那就是冲突 让我的理解变得复杂的是 更改 X 行 可能意味着用几行新行替换它 但这仍然显示为一
  • 如何将普通的 Git 存储库转换为裸存储库?

    如何将 普通 Git 存储库转换为裸存储库 主要区别似乎是 在普通的 Git 存储库中 你有一个 git存储库内的文件夹 包含构成工作副本的所有相关数据和所有其他文件 在裸露的 Git 存储库中 没有工作副本和文件夹 我们称之为repo g
  • 如何通过哈希显示提交的日期和时间

    I used git reflog识别我创建特定分支时的哈希值 我得到了哈希值fe1ddcdef 我还没有将此分支推送到远程 我现在正在尝试查找日期和时间fe1ddcdef发生 git reflog只告诉我 fe1ddcdef HEAD 1
  • gitlab 上的权限被拒绝(公钥)

    我的问题是我无法从 GitLab 推送或获取 不过 我可以克隆 通过 HTTP 或通过 SSH 当我尝试推送时出现此错误 权限被拒绝 公钥 致命 无法从远程存储库读取 从我看过的所有线程中 这是我所做的 在我的计算机上设置 SSH 密钥并将
  • TeamCity 将功能分支推送到主分支

    有没有办法将成功构建的功能分支推送到另一个分支 我想要这样的东西 Git 存储库 Gitorious GitHub 等 分支机构 master 当前项目的代码 质量保证 代码等待 QA 的分支 功能分支 许多远程分支 开发人员可以在其中开发
  • 从 github 中删除子项目提交

    我有两个存储库A and B 我错误地在我的机器上将仓库 B 克隆到了 A 内 我从存储库 B 中删除了所有代码 但是当我在源上从 A 推送并合并代码时 它还显示了子项目提交B在 Github 仓库上 我想从我的 master 上删除子项目
  • 获取最新远程提交的 SHA1 [重复]

    这个问题在这里已经有答案了 可能的重复 git bash 如何检查是否有新的提交可用 https stackoverflow com questions 6006759 git bash how to check if theres a n
  • Visual Studio Code 内置故事,用于查看 git 提交历史记录并对其内容进行比较

    In this https stackoverflow com questions 37899765 how can i view the git history in visual studio code 60013101 noredir
  • 致命:不是 git 存储库(或任何父目录):.git [重复]

    这个问题在这里已经有答案了 当我尝试推送 github com 上的现有存储库时 当我输入命令时 网站提示我将其输入终端 我收到了以下致命错误消息 Not a git repository or any of the parent dire
  • 按时间顺序将多个文件夹提交到 git 中

    我有数百个网站备份 每个文件夹一个 我想将它们放入 git 存储库中 每个备份作为一个版本 这些变化主要涉及图像文件和每天 2 个数据库备份 大小约为 25 GB 并且不断增加 有没有办法告诉 git 获取其中一个文件夹并将其提交到存储库中

随机推荐

  • qt开发的程序 为何一个主窗口关闭了,程序不退出,而是到等到所有窗口关闭了,才退出呢?

    这种行为是由Qt框架中的事件循环 Event Loop 机制引起的 Qt应用程序在执行时 会进入一个事件循环 该循环负责处理用户输入 事件和信号 并相应地调用相应的槽函数或处理程序 当你关闭一个Qt应用程序的主窗口时 主窗口会发出一个关闭事
  • 二进制模2除法(CRC校验)

    二进制模2除法与二进制除法不同 模2运算 加法不进位 减法不借位 二进制除法 带借位的二进制除法 根据余数减除数够减与否 确定商1还是商0 若够减则商1 否则商0 二进制模2除法 采用模2减法 不带借位的二进制减法 因此考虑余数够减除数与否
  • 制作论文中双Y轴散点图

    import pandas as pd import matplotlib pyplot as plt from matplotlib dates import AutoDateLocator DateFormatter from date
  • Unity开发优化----删除多余的MeshCollider和Animation组件

    手游项目做碰撞的时候 有关一切物理的东西Unity对手机支持的并不好 多余的MeshCollider 和Animation 空的组件 这俩东西很占效率的 比如下图这样的组件 还有场景的材质最好用Mobile Diffuse 它会比Diffu
  • SQL注入联合注入

    SQL注入定义 SQL是操作数据库数据的结构化查询语言 网页的应用数据和后台数据库中的数据进行交互时会采用SQL SQL注入是指将Web页面的原URL 表单域或数据包输入的参数 修改拼接成SQL语句 传递给Web服务器 进而传给数据库服务器
  • fopen与fopen_s的区别

    在定义FILE fp 之后 fopen的用法是 fp fopen filename w 而对于fopen s来说 还得定义另外一个变量errno t err 然后err fopen s fp filename w 返回值的话 对于fopen
  • 中国移动智能家庭网关(类型二)默认账号和密码

    超级账号 CMCCAdmin 超级密码 aDm8H MdA 超级用户名 telecomadmin 超级密码 nE7jA 5m 用户名 telecomadmin 密码 admintelecom 超级用户名 fiberhomehg2 0 超级密
  • Win10更新后开机变得很慢怎么办?Win10更新后开机变得很慢解决方法

    Win10更新后开机变得很慢怎么办 尽管Win10提供了许多强大的功能和改进 但有些用户在系统升级后可能会遇到开机变慢的问题 让用户们感到困扰 因为开机速度直接关系到使用计算机的效率和便捷性 以下小编将给用户们介绍Win10更新后开机变得很
  • Ancona虚拟环境创建失败

    anaconda虚拟环境创建失败 报错信息如最下 参考了这篇解决方法 先输入conda clean i 再创建虚拟环境就成功了 conda clean i Solving environment failed gt gt gt gt gt
  • 七位高僧大德的临终开示,非大福报者不得见

    http www xuefo net nr article47 465546 html 一 印光大师 印光大师临终时当晚对身边的弟子说 净土法门 别无奇特 只要恳切至诚 没有不蒙佛接引 带业往生 此后精神逐渐疲惫 体温降低 夜里一时半 大师
  • 仿函数(functors)

    functor 仿函数 或者称之为function object 函数对象 是STL的四大组件之一 什么是仿函数呢 一个函数对象是封装在类中 从而看起来更像是一个对象 这个类只有一个成员函数 即重载了 括号 的运算符 它没有任何数据 该类被
  • 工频干扰频谱测量_经验分享

    正文 2219 字 丨 7 分钟阅读 导读 本文的内容是关于转动设备常见振动故障频谱特征及案例分析 非常实用的经验总结 希望对你的工作和学习有所帮助 一 不平衡 转子不平衡是由于转子部件质量偏心或转子部件出现缺损造成的故障 它是旋转机械最常
  • WinCE系统下基于DirectShow的摄像头应用编程

    大家可以对比我的另一篇文章学习 XP下基于DirectShow的摄像头采集 转载自 http blog csdn net northcan article details 7268745 在WinCE设备上使用摄像头时 一般都是向厂家索要驱
  • CentOS离线安装PostgreSQL12.4及PostGIS30_12

    PostgreSQL12 4及PostGIS3 0安装 一 安装PostgreSQL12 4 1 下载rpm安装包 用rpm ivh命令依次安装 2 查看安装信息 3 初始化数据库 4 配置开机启动 5 修改密码 6 查看数据存储路 7 查
  • mysql如何快速生成百万条测试数据

    想要在mysql中快速生成百万条测试数据如果使用SQL批量插入显然工作量会很大 可以利用内存表插入数据快的特点 再调用存储过程往内存表插入数据 从内存表中查询数据插入到普通表的思路来解决问题 1 创建内存表 CREATE TABLE vot
  • 2023金九银十软件测试面试题(800道)

    今年你的目标是拿下大厂offer 还是多少万年薪 其实这些都离不开日积月累的过程 为此我特意整理出一份 超详细笔记 面试题 它几乎涵盖了所有的测试开发技术栈 非常珍贵 人手一份 肝完进大厂 妥妥的 由于细节内容实在太多啦 所以只把部分知识点
  • xgboost优化_什么是xgboost以及如何对其进行优化

    xgboost优化 介绍 Introduction Like many data scientists XGBoost is now part of my toolkit This algorithm is among the most p
  • 谷歌云

    Cloud Ace 是谷歌云全球战略合作伙伴 拥有 300 多名工程师 也是谷歌最高级别合作伙伴 多次获得 Google Cloud 合作伙伴奖 作为谷歌托管服务商 我们提供谷歌云 谷歌地图 谷歌办公套件 谷歌云认证培训服务 您知道通过调整
  • 静态逆向简单的ELF

    看到csdn中一篇文章 http blog csdn net fisher jiang article details 6783922 该文章使用动态调试进行破解找到密码 由于自己对linux不熟悉需要学习段时间 就使用ida静态反汇编进行
  • gerrit "missing Change-Id"

    场景 你用 git push 向 gerrit 提交了待审核代码 一切都很顺利 你脑袋里冒出了 代码头上加了 佛祖保佑 果然有效 的想法 此时 git 打印出如下提示 你的内心OS同步打印 心情 5 remote Resolving del