Git提交前的必备神器——自动清除调试语句脚本

说在前面

不知道大家有没有遇到这样一种情况,平时在写代码调试时有时候会使用到debugger,可能大部分时间在提交代码前会记得把debugger先删除,但可能也会存在将debugger提交上去的情况,那我们该怎么防止出现这种情况呢?

当要提交代码时,通常会避免将调试语句debugger一同提交到版本库中。为了解决这个问题,你编写了一个脚本来自动清除代码中的debugger语句,并将修改后的文件添加到Git暂存区。在这篇博客中,我们将介绍这个脚本的实现原理和使用方法,帮助开发者更有效地管理和提交代码。

webpack 配置修改

开发过程中,经常需要使用console.logconsole.infoalert等操作来输出内容,测试代码,而在生产环境之中,这些打印的东西最好是不要显示、特别是用户名、密码相关。

一个个去删除、注释显然是很麻烦的一件事,所以我们可以通过修改配置变量,实现在开发环境打印,而生产环境不打印。

修改方法如下:
在项目的build/webpack.prod.conf.js文件之中,找到UglifyJsPlugin配置,在compress中添加如下代码即可。

new UglifyJsPlugin({uglifyOptions: { compress: { warnings: false, // 打包的时候移除console、debugger drop_debugger: true, // 移除debugger drop_console: true, // 移除console pure_funcs: ['console.log','console.info']}},sourceMap: config.build.productionSourceMap,parallel: true
}),

git hook监测删除

除了直接在webpack中配置之外,我们还可以在git提交前进行监测,将修改文件中的相关语句清除,这里以清除修改文件中的debugger语句为例子:

git hook简单了解

Git钩子是一组脚本,这些脚本对应着Git仓库中的特定事件,每一次事件发生时,钩子会被触发。这允许你可以定制化Git的内部行为,在开发周期中的关键点上触发执行定制化的脚本。

image.png

钩子脚本文件通常放置于项目目录的.git/hooks文件夹下。Git会在初始化项目时自动在这个文件夹下放置一些样例脚本。如果你查看.git/hooks文件夹下,会找到如下的文件:

image.png

我们可以简单了解一下这些钩子的触发时机:

  • applypatch-msg

这个钩子由git-am调用。它接受一个参数,即保存提议的提交日志消息的文件的名称。以非零状态退出导致git am在应用补丁之前中止。

允许钩子就地编辑消息文件,并可用于将消息规范化为某种项目标准格式。它还可以用于在检查消息文件后拒绝提交。

默认的applypatch-msg钩子在启用时,如果启用了commit-msg钩子,则运行commit-msg钩子。

  • commit-msg

这个钩子由git-commitgit-merge调用,可以通过——no-verify选项绕过。它接受一个参数,即保存提议的提交日志消息的文件的名称。以非零状态退出将导致命令中止。

允许钩子就地编辑消息文件,并可用于将消息规范化为某种项目标准格式。它还可以用于在检查消息文件后拒绝提交。

默认的commit-msg钩子在启用时,会检测到重复的挂件签到,如果发现了,就会中止提交。

  • fsmonitor-watchman

这个钩子在配置选项核心时被调用。根据要使用的钩子的版本,Fsmonitor被设置为.git/hooks/ Fsmonitor -watchman或.git/hooks/ Fsmonitor -watchmanv2。

Version 1有两个参数,一个是Version(1),另一个是自1970年1月1日午夜以来经过的纳秒时间。

Version 2有两个参数,一个是Version(2),另一个是token(用于标识token之后的更改)。对于守望者来说,这是一个时钟id。这个版本必须在文件列表之前向stdout输出新的令牌,后跟一个NUL。

钩子应该向stdout输出工作目录中自请求时间以来可能发生更改的所有文件的列表。逻辑应该是包容性的,这样它就不会错过任何潜在的更改。这些路径应该是相对于工作目录的根目录的,并由单个NUL分隔。

包含实际上没有更改的文件是可以的。应该包括所有更改,包括新创建和删除的文件。当重命名文件时,应该同时包含旧的和新的名称。

Git将根据给定的路径名限制检查更改的文件,以及检查未跟踪文件的目录。

告诉git“所有文件都已更改”的一种优化方法是返回文件名/。

退出状态决定git是否会使用来自钩子的数据来限制它的搜索。如果出现错误,它将退回到验证所有文件和文件夹。

  • post-update

git-receive-pack响应git push并更新其存储库中的引用时,会调用该钩子。当所有引用都被更新后,它会在远程存储库上执行一次。

它接受可变数量的参数,每个参数都是实际更新的ref的名称。

这个钩子主要用于通知,不会影响git receive-pack的结果。

post-update钩子可以告诉我们被推送的头是什么,但它不知道它们的原始值和更新值是什么,所以这是一个糟糕的地方。post-receive钩子获取ref的原始值和更新后的值。如果你需要的话,你可以考虑一下。

当启用时,默认的post-update钩子会运行git update-server-info来保持哑传输(例如HTTP)使用的信息是最新的。如果你要发布一个可以通过HTTP访问的Git存储库,你应该启用这个钩子。

标准输出和标准错误输出都被转发到另一端的git send-pack,因此您可以简单地为用户回显消息。

  • pre-commit

这个钩子由git-commit调用,可以通过——no-verify选项绕过。它不接受任何参数,在获得建议的提交日志消息并进行提交之前调用。以非零状态退出该脚本会导致git commit命令在创建提交之前终止。

默认的预提交钩子在启用时,会捕获带有尾随空格的行,并在找到这样的行时中止提交。

所有的git提交钩子都是用环境变量GIT_EDITOR=:来调用的,如果这个命令不会调出一个编辑器来修改提交消息。

默认的预提交钩子(当启用时)和钩子。allownonascii配置选项取消设置或设置为false -防止使用非ascii文件名。

  • pre-merge-commit

这个钩子由git-merge调用,可以用——no-verify选项绕过。它不接受任何参数,并且在成功执行合并之后,在获得建议的提交日志消息以进行提交之前调用。以非零状态退出该脚本会导致git merge命令在创建提交之前终止。

默认的预合并提交钩子在启用时,如果启用了预提交钩子,则运行预提交钩子。

如果该命令不会调出编辑器来修改提交消息,则使用环境变量GIT_EDITOR=:调用该钩子。

如果合并不能自动执行,则需要解决冲突并单独提交结果(参见git-merge[1])。此时,此钩子将不会被执行,但如果启用了预提交钩子,则会执行。

  • prepare-commit-msg

这个钩子被git-commit调用,在准备默认日志消息之后,在编辑器启动之前。

它需要一到三个参数。第一个是包含提交日志消息的文件的名称。第二个是提交消息的来源,可以是:message(如果给出了-m或-F选项);模板(如果给出了-t选项或配置选项commit)。模板设置);merge(如果提交是merge或者.git/MERGE_MSG文件存在);(如果.git/SQUASH_MSG文件存在);或commit,后跟提交对象名称(如果给出了-c、-c或——amend选项)。

如果退出状态非零,git commit将中止。

钩子的目的是就地编辑消息文件,它不会被——no-verify选项抑制。非零退出意味着钩子失败并终止提交。它不应该被用作预提交钩子的替代品。

Git附带的样例prepare-commit-msg钩子删除了提交模板注释部分中的帮助消息。

  • pre-push

这个钩子由git-push调用,可以用来阻止push的发生。钩子是用两个参数调用的,这两个参数提供了目标远程的名称和位置,如果没有使用命名的远程,两个值将是相同的。

关于要推送的内容的信息在钩子的标准输入中提供,格式如下:

<local ref> SP <local object name> SP <remote ref> SP <remote object name> LF
例如,如果命令git push origin master:foreign被运行,钩子会收到像下面这样的一行:

参考/头/主67890参考/头/外12345
尽管将提供完整的对象名称。如果外部ref还不存在,<远程对象名>将是全零对象名。如果要删除一个ref, <local ref>将作为(delete)提供,<local object name>将是全零对象名称。如果本地提交不是由可以扩展的名称(例如HEAD~,或者对象名称)指定的,那么它将按照最初给出的方式提供。

如果这个钩子以非零状态退出,git push将不推送任何东西而中止。关于拒绝推送的原因的信息可以通过写入标准错误发送给用户。

  • pre-rebase

这个钩子由git-rebase调用,可以用来防止分支被rebase。钩子可以带一个或两个参数调用。第一个参数是序列分叉的上游。第二个参数是正在重基的分支,在重基当前分支时不设置。

  • pre-receive

当git-receive-pack响应git push并更新其存储库中的引用时,会调用该钩子。就在开始更新远程存储库上的引用之前,调用预接收钩子。其退出状态决定了更新的成功或失败。

这个钩子执行一次接收操作。它不接受任何参数,但对于每个要更新的ref,它会在标准输入中接收一行格式如下:

SP <new-value> SP <ref-name> LF
其中<old-value>是存储在ref中的旧对象名称,<new-value>是存储在ref中的新对象名称,<ref-name>是ref的全名。创建新ref时,<old-value>是全零对象名称。

如果钩子以非零状态退出,则不会更新任何引用。如果钩子以0退出,更新钩子仍然可以阻止更新单个引用。

标准输出和标准错误输出都被转发到另一端的git send-pack,因此您可以简单地为用户回显消息。

git push命令行给出的push选项数——push-option=…可以从环境变量GIT_PUSH_OPTION_COUNT中读取,选项本身在GIT_PUSH_OPTION_0, GIT_PUSH_OPTION_1,…中找到,如果协商不使用推送选项阶段,则不会设置环境变量。如果客户端选择使用推送选项,但不传输任何选项,则计数变量将被设置为零,GIT_PUSH_OPTION_COUNT=0。

有关一些注意事项,请参阅gift -receive-pack中的“隔离环境”一节。

  • push-to-checkout

git-receive-pack响应git push并更新其存储库中的引用时,以及当push尝试更新当前签出的分支并且receive.denyCurrentBranch配置变量设置为updateInstead时,该钩子被git-receive- receive-pack调用。默认情况下,如果工作树和远程存储库的索引与当前签出的提交有任何差异,则拒绝这样的推送;当工作树和索引都匹配当前提交时,它们将被更新以匹配新推送的分支尖端。此钩子将用于覆盖默认行为。

钩子接收当前分支的尖端将被更新的提交。它可以以非零状态退出以拒绝推送(当它这样做时,它不能修改索引或工作树)。或者,它可以对工作树和索引进行任何必要的更改,使它们在当前分支的尖端更新到新提交时达到所需的状态,并以零状态退出。

例如,钩子可以简单地运行git read-tree -u -m HEAD "$1",以模拟git fetchgit push相反的方向运行,因为git read-tree -u -m的两树形式本质上与git switchgit checkout相同,它们在切换分支的同时保持工作树中的本地更改,而不会干扰分支之间的差异。

  • update

git-receive-pack响应git push并更新其存储库中的引用时,会调用该钩子。就在更新远程存储库上的ref之前,调用更新钩子。它的退出状态决定了refupdate的成功或失败。

对于每个要更新的ref,钩子执行一次,并接受三个参数:

被更新的ref的名称,

旧的对象名称存储在ref,

以及要存储在ref中的新对象名称。

update钩子的零退出允许更新ref。以非零状态退出会阻止git receive-pack更新该ref。

这个钩子可以用来防止某些refs上的强制更新,通过确保对象名称是一个提交对象,是由旧对象名称命名的提交对象的后代。也就是说,执行“仅快进”策略。

它也可以用来记录新旧状态。然而,它并不知道分支的全部集合,因此在天真地使用时,它最终会为每个ref发送一封电子邮件。post-receive钩子更适合于此。

在限制用户只能通过网络访问git命令的环境中,这个钩子可以用来实现访问控制,而不依赖于文件系统所有权和组成员关系。请参阅git-shell[1]了解如何使用登录shell来限制用户只能访问git命令。

标准输出和标准错误输出都被转发到另一端的git send-pack,因此您可以简单地为用户回显消息。

默认的更新钩子,当启用时——并且带有钩子。允许unannotated配置选项unset或设置为false -防止未注释的标签被推送。

完整钩子说明,请参考官网链接

脚本逻辑

1、声明脚本运行环境

这里我们使用node进行编写,所以脚本运行环境应该声明为node

#!/usr/bin/env node
2、获取当前暂存更改的文件信息

我们可以使用git status来获取当前暂存更改的文件目录,但部分同学可能会出现获取到的文件名中文只显示字符串的情况:

image.png

  • 原因

在默认设置下,中文文件名在工作区状态输出,中文名不能正确显示,而是显示为八进制的字符编码。

  • 解决办法

将git 配置文件 core.quotepath项设置为false。
quotepath表示引用路径
加上–global表示全局配置

git bash 终端输入命令:

git config --global core.quotepath false

image.png

我们可以看到修改过的文件路径。

3、提取 git status 信息中的变动文件路径

上一步我们知道了可以使用git status命令来获取暂存更改的文件信息,但获取到的信息并不是直接得到变动的文件路径,我们需要从获取到的信息中的变动文件路径。

let commitFile = child_process.execSync(command).toString();
commitFile = commitFile.split("\n");
console.log("commitFile: ", commitFile);

image.png

这里前面的五行其实是固定的,我们只需要从第六行开始获取即可,文件路径与变更类型描述是通过:隔开,所以我们分割一下:,再将一些特殊字符去掉即可。

const child_process = require("child_process");
const trimReg = /(\ +)|([ ])|([\r\n]|(["]))/g;
const fileList = [];
for (let i = 5; i < commitFile.length; i++) {const name = commitFile[i].split(":")[1];if (!name) break;fileList.push(decodeURI(name.replace(trimReg, "")));
}
console.log("fileList: ", fileList);

image.png

4、判断文件中是否包含 debugger

通过readFileSync获取文件内容,判断文件内容是否包含debugger,包括的话将文件路径记录并将文件中的debugger全部删除,然后再将修改后的文件重新git add -文件路径提交即可。

const child_process = require("child_process");
const fs = require("fs");
const editFiles = [];
fileList.forEach((file) => {const txt = fs.readFileSync(file, "utf8");if (txt.includes("debugger")) {editFiles.push(file);fs.writeFileSync(file, txt.replace(/(debugger);?(\s*\n)*/g, ""));const commandAdd = "git add " + file;child_process.execSync(commandAdd).toString();}
});
console.log("editFiles: ", editFiles);
console.log("已清除提交文件中的 debugger");

完整代码

#!/usr/bin/env node
const child_process = require("child_process");
const fs = require("fs");
const command = "git status";
const trimReg = /(\ +)|([ ])|([\r\n]|(["]))/g;
let commitFile = child_process.execSync(command).toString();
commitFile = commitFile.split("\n");
const fileList = [];
for (let i = 5; i < commitFile.length; i++) {const name = commitFile[i].split(":")[1];if (!name) break;fileList.push(decodeURI(name.replace(trimReg, "")));
}
const editFiles = [];
fileList.forEach((file) => {const txt = fs.readFileSync(file, "utf8");if (txt.includes("debugger")) {editFiles.push(file);fs.writeFileSync(file, txt.replace(/(debugger);?(\s*\n)*/g, ""));const commandAdd = "git add " + file;child_process.execSync(commandAdd).toString();}
});
console.log("editFiles: ", editFiles);
console.log("已清除提交文件中的 debugger");
process.exit(0);

参考材料

https://zhuanlan.zhihu.com/p/521707440

https://git-scm.com/docs/githooks

公众号

关注公众号『前端也能这么有趣』,获取更多有趣内容。

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/231100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RLC防孤岛负载测试:电力系统安全运行的重要保障

在电力系统中&#xff0c;孤岛效应是一个严重的问题&#xff0c;它可能导致电力系统的不稳定甚至崩溃。为了确保电力系统的安全运行&#xff0c;必须进行RLC防孤岛负载测试。RLC防孤岛负载测试是一种模拟电网故障后&#xff0c;对电力系统进行检测的方法&#xff0c;主要用于检…

在 linux上运行 Scratch,找到了更github 的项目地址,而且找到了scratch的官方项目。

1&#xff0c;关于Scratch Scratch 是麻省理工学院的“终身幼儿园团队”发布的一种图形化编程工具&#xff0c; 主要面对全球青少年开放&#xff0c;所有人都可以在软件中创作自己的程序。 2&#xff0c;在linux 上面还真有个默认的 scratch 版本 但是太老旧了。 于是找了下…

天猫数据分析平台-天猫销售数据查询软件-11月天猫平台冲锋衣市场销售运营数据分析

随着气温逐渐下降&#xff0c;保暖服饰迎来热销&#xff0c;冲锋衣的需求大增。如今冲锋衣已经不仅仅是户外运动的装备&#xff0c;还成为很多年轻人的日常穿搭和时尚的追求。 新的穿搭趋势也带来了巨大的市场机会。据公开数据显示&#xff0c;中国有冲锋衣生产及经营企业超过8…

分布式事务--TC服务的高可用和异地容灾

1.模拟异地容灾的TC集群 计划启动两台seata的tc服务节点&#xff1a; 节点名称ip地址端口号集群名称seata127.0.0.18091SHseata2127.0.0.18092HZ 之前我们已经启动了一台seata服务&#xff0c;端口是8091&#xff0c;集群名为SH。 现在&#xff0c;将seata目录复制一份&…

9. DashBoard

9. DashBoard 文章目录 9. DashBoard9.1 部署Dashboard9.2 使用DashBoard 在kubernetes中完成的所有操作都是通过命令行工具kubectl完成的。 为了提供更丰富的用户体验&#xff0c;kubernetes还开发了一个基于web的用户界面&#xff08;Dashboard&#xff09;。 用户可以使用…

【计算机网络】TCP协议——2.连接管理(三次握手,四次挥手)

目录 前言 一. 建立连接——三次握手 1. 三次握手过程描述 2. TCP连接建立相关问题 二. 释放连接——四次挥手 1. 四次挥手过程描述 2. TCP连接释放相关问题 三. TCP状态转换 结束语 前言 TCP——传输控制协议(Transmission Control Protocol)。是一种面向连接的传…

被我们忽略的HttpSession线程安全问题

1. 背景 最近在读《Java concurrency in practice》(Java并发实战)&#xff0c;其中1.4节提到了Java web的线程安全问题时有如下一段话&#xff1a; Servlets and JPSs, as well as servlet filters and objects stored in scoped containers like ServletContext and HttpSe…

用“价值”的视角来看安全:《构建新型网络形态下的网络空间安全体系》

作者简介&#xff1a; 懒大王敲代码&#xff0c;正在学习嵌入式方向有关课程stm32&#xff0c;网络编程&#xff0c;数据结构C/C等 今天给大家介绍《构建新型网络形态下的网络空间安全体系》这本书&#xff0c;希望大家能觉得实用&#xff01; 欢迎大家点赞 &#x1f44d; 收藏…

【C语言】鹏哥C语言刷题训练营——第5节内容笔记(含代码全面分析和改进,讲解)

系列文章目录 身躯已然冰封&#xff0c;灵魂仍旧火热 本文由睡觉待开机原创&#xff0c;未经允许不得转载。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言&#xff0c;共同进步&#xff01; 文章目录 系列文章目录前言题目链接&#xff08;有需要…

阿里云部署k8s with kubesphere

阿里云ESC 创建实例 填入密码即可 云上的防火墙相关设置就是安全组 vpc 专有网络 划分私有ip 子网 vpc 隔离环境域 不同的vpc下 即使相同的子网也不互通 使用交换机继续划分子网 停止 释放 不收钱 k8s 服务器 4核8G*1 8核16G *2 git 创建凭证 pipeline 发邮箱 (p124)…

双指针算法(二)

三数之和 三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重…

Linux---Ubuntu软件安装

1. 软件安装的介绍 Ubuntu软件安装有两种方式: 离线安装(deb文件格式安装&#xff09;在线安装(apt-get方式安装) 2. deb文件格式安装 是 Ubuntu 的安装包格式&#xff0c;可以使用 dpkg 命令进行软件的安装和卸载。 命令说明dpkg安装和卸载deb安装包 dpkg命令选项: 选项…

数字滤波器设计——Matlab实现数字信号处理<1>

目录 一.实验内容 二.代码分析 1.信号产生部分 2.利用傅立叶级数展开的方法&#xff0c;自由生成所需的x(t) 3.通过选择不同的采样间隔T&#xff08;分别选T>或<1/2fc&#xff09;&#xff0c;从x(t)获得相应的x(n) 3.对获得的不同x(n)分别作傅立叶变换&#xff0c…

2024年高效远程协同运维工具推荐

随着企业的不断发展以及变化&#xff0c;企业的内部IT环境也是日益复杂&#xff0c;一跨高效远程协同运维工具必不可少&#xff0c;不仅可以提高生产力&#xff0c;还能降低运营成本。这里就给大家推荐2024年高效远程协同运维工具。 高效远程协同运维工具应用场景 1、IT运维管…

安卓端出现https请求失败(转)

背景# 某天早上&#xff0c;正在一个会议时&#xff0c;突然好几个同事被叫出去了&#xff1b;后面才知道&#xff0c;是有业务同事反馈到领导那里&#xff0c;我们app里面某个功能异常。 具体是这样&#xff0c;我们安卓版本的app是禁止截屏的&#xff08;应该是app里做了拦…

设计模式(三)-结构型模式(2)-桥接模式

一、为何需要桥接模式&#xff08;Bridge&#xff09;? 在软件设计中&#xff0c;存在有两个或多个不同维度的模块时&#xff0c;我们需要将这些模块使用到在一起&#xff0c;来实现一个完整的功能。所谓不同维度的意思就是这些模块所负责的职责是不同的&#xff0c;并且它们…

lua安装

lua安装 1.Lua介绍 特点&#xff1a;轻量、小巧。C语言开发。开源。 设计的目的&#xff1a;嵌入到应用程序当中&#xff0c;提供灵活的扩展和定制化的功能。 luanginx&#xff0c;luaredis。 2.windows安装lua windows上安装lua&#xff1a; 检查机器上是否有lua C:\U…

Kubernetes 的用法和解析 -- 4

一.Deployment 资源详解 如果Pod出现故障&#xff0c;对应的服务也会挂掉&#xff0c;所以Kubernetes提供了一个Deployment的概念 &#xff0c;目的是让Kubernetes去管理一组Pod的副本&#xff0c;也就是副本集 &#xff0c;这样就能够保证一定数量的副本一直可用&#xff0c;…

概率论复习

第一章&#xff1a;随机概率及其概率 A和B相容就是 AB 空集 全概率公式与贝叶斯公式&#xff1a; 伯努利求概率&#xff1a; 第二章&#xff1a;一维随机变量及其分布&#xff1a; 离散型随机变量求分布律&#xff1a; 利用常规离散性分布求概率&#xff1a; 连续性随机变量…

Windows使用VNC Viewer远程桌面Ubuntu【内网穿透】

文章目录 前言1. ubuntu安装VNC2. 设置vnc开机启动3. windows 安装VNC viewer连接工具4. 内网穿透4.1 安装cpolar【支持使用一键脚本命令安装】4.2 创建隧道映射4.3 测试公网远程访问 5. 配置固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址5.3 测试…