如何识别 Git 中的强制推送?

问题描述 投票:0回答:1

通过查看我团队的提交日志,我发现同一补丁中的代码更改行在不同的提交中出现了两次。

进一步证明是这样的:Master分支在其更改列表中有提交A(如“git log”中所示)。 如果我将提交 A 作为 HEAD 检查,我可以在其更改列表中找到提交 B。 但是,如果我将 master 签出为 HEAD,我无法在其更改列表中找到提交 B。 我相信在某个时刻发生了非快进的推动。但是有没有简单的方法可以通过使用 git 命令或其他工具来识别这种非快进推送呢?

git push blame
1个回答
1
投票

使用

Github v4 API

强制推送 应该PullRequest 的 时间轴上作为 BaseRefForcePushedEvent 和/或 HeadRefForcePushedEvents 可用。

如果您有权访问裸远程存储库,您

可能能够检测到强制推送,但这很复杂。下面我会举例说明。 通常推送是建立在现有提交之上的。如果你有一个本地仓库,在你的远程仓库之前有一些提交,就像这样......

origin A - B - C [master] local A - B - C [origin/master] \ D - E [master]

git push

D 和 E 将被发送,并且本地和远程将具有相同的

master
历史记录。

origin A - B - C - D - E [master] local A - B - C - D - E [master][origin/master]

但是如果
local

做了一些变基,假设他们重写了B,历史就“分歧”了。


origin A - B - C - D - E [master] local A - B - C - D - E [origin/master] \ B1 - C1 - D1 - E1 [master]

现在如果你尝试推送它会被拒绝,
git push

不会为你合并,它只会快进。这通常可以通过

git push --force
来解决,它只是替换现有的历史记录。

origin A - B - C - D - E \ B1 - C1 - D1 - E1 [master] local A - B - C - D - E \ B1 - C1 - D1 - E1 [origin/master][master]

请注意,旧的提交仍然存在,无论是在您的本地还是原点。它们将一直留在那里,直到发生垃圾收集,通常持续数周。

在本地,您可以使用

git-reflog

 查看旧提交。远程存储库
可能有一个引用日志,如果是的话你很幸运。但也可能不会。然而旧的提交仍然存在。 您可以在

objects

目录中看到它们。提交 53715b45364b160ce6e36d934be903459aebe254 在文件中

objects/53/715b45364b160ce6e36d934be903459aebe254
...尽管为了提高效率可能会
打包
所以提交可能仍然存在,但是如何找到变基的证据呢?一个技巧是运行“垃圾收集”并查看还剩下什么。

git gc

只会打包引用的提交,并且它将保存不到两周的未引用提交(这可以使用各种“修剪”配置选项进行配置)。 objects 中留下的任何提交都可能是旧提交。


$ find objects -type f objects/3b/d1f0e29744a1f32b08d5650e62e2e62afb177c objects/5f/941d2600a72d0126689ee1d51225cb7d3c0a05 objects/33/f273a8ea4378453f297dc9a69e81a374534361 objects/02/5f398bbc061f1fa0b61f8454f5d134f43a8a4c objects/d7/3afbb06ed2245a0c82ab147ea28eabeb41196e objects/b4/036885119a0c0a726d4a07c39880f5d4e5d688 objects/7d/311b920e2b6ba8ac14198c1a30fe41af8e34fe objects/42/e2ac33f56ca2b7f51c87db4baeb66980525c40 objects/19/6803e246079172e91973f583672290988e89c9 objects/81/7b794bceb50878e569b18a336e52181c3bf45c objects/86/e041dad66a19b9518b83b78865015f62662f75 objects/9a/095aeaea32de8059face7ff2ccea63a2337dbb objects/09/1dddfa09138dc26cbf0dec4603a4aa95001d1c objects/53/715b45364b160ce6e36d934be903459aebe254 objects/0a/f001a378ba6af70af76c10466b90c8f96e8403 objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 objects/84/d0a65b5b8b4d9376f08e3c4518057b16ee6082 objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99

旧的提交是

53715b45364b160ce6e36d934be903459aebe254
b4036885119a0c0a726d4a07c39880f5d4e5d688

025f398bbc061f1fa0b61f8454f5d134f43a8a4c
。运行后
git gc
...

$ git gc Enumerating objects: 15, done. Counting objects: 100% (15/15), done. Delta compression using up to 8 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (15/15), done. Building bitmaps: 100% (5/5), done. Total 15 (delta 0), reused 0 (delta 0) Computing commit graph generation numbers: 100% (5/5), done. $ find objects -type f objects/02/5f398bbc061f1fa0b61f8454f5d134f43a8a4c objects/b4/036885119a0c0a726d4a07c39880f5d4e5d688 objects/pack/pack-57c98c590b41d20da1b6892ce4a18ab735272583.pack objects/pack/pack-57c98c590b41d20da1b6892ce4a18ab735272583.bitmap objects/pack/pack-57c98c590b41d20da1b6892ce4a18ab735272583.idx objects/info/commit-graph objects/info/packs objects/53/715b45364b160ce6e36d934be903459aebe254

未引用的提交未打包。

我不知道这种技术有多万无一失,但它使得找到最近强制推送的证据成为可能。

解决这个问题的最佳选择就是一开始就不拥有它。

如果您不允许直接提交到
master

,要求所有提交都通过 PR 完成,这可以确保您记录了进入

master

的所有内容,并且对

master
的所有添加都是通过干净的合并完成的,并且没有人(管理员除外)可以更改主人的历史记录。与自动检查和测试相结合,这可确保
master
始终处于良好状态,并且团队拥有坚实的工作基础。

此外,rebase后强制推送是正常的,但正常的
git push --force
仍然是危险的。相反,在变基后使用

git push --force-with-lease

进行推送。这将检查是否仅强制推送通过变基更改的提交。

git push --force-with-lease
使变基更安全。我将其别名为
git repush
    

© www.soinside.com 2019 - 2024. All rights reserved.