

git hook+expand+unexpand化解空格与TAB之争
source link: https://www.lujun9972.win/blog/2020/04/29/git-hook+expand+unexpand%E5%8C%96%E8%A7%A3%E7%A9%BA%E6%A0%BC%E4%B8%8Etab%E4%B9%8B%E4%BA%89/index.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

git hook+expand+unexpand化解空格与TAB之争
SPACE与TAB之争由来已久,但是有一个观点是两派都公认赞同的,那就是 不能两者混用.
为此,Linux很贴心的提供了 expand
和 unexpand
命令来帮助我们进行 TAB
和 SPACE
之间的相互转换。
使用expand将TAB转换为SPACE
使用expand将TAB转换为SPACE的方法很简单,直接执行 expand 文件
就会把 文件
中的所有 TAB
都替换空格(默认按8个空格进行对齐)了。
例如假设我们有下面一个测试文件
cat -T /tmp/test
^Ihello ^Itest^I
其中 cat
的 -T
选项文件内容其中的 TAB
显示为 ^I
我们现在来用 expand
对其进行转换
expand /tmp/test |cat -T
hello test
如果觉得使用8空格对齐太空了,那么可以使用 -t
选项指定对齐的空格数。比如下面命令按4个空格进行对齐:
expand -t 4 /tmp/test |cat -T
hello test
另一方面,我们在写代码时可能只需要转换行首的空格,而字符串中的 TAB
是不需要进行转换的,那么就可以使用 -i
选项指定 expand
只对行首的空格进行转换:
expand -i -t 4 /tmp/test |cat -T
hello ^Itest^I
使用unexpand将SPACE转换为TAB
unexpand
, 从名字上就知道它是 expand
的反操作,即把SPACE转换为TAB.
他们的使用方法也很类似,但是有一点不同就是 expand
在默认情况下替换所有的 TAB
,当只替换行首的 TAB
时需要指定 -i
选项;而 unexpand
在默认情况下只替换行首的 SPACE
,若要替换 SPACE
时需要明确指定 -a
选项.
还是例如假设我们有下面一个测试文件
cat -T /tmp/test.space
hello test
我们现在来用 unexpand
对其进行转换
unexpand /tmp/test.space |cat -T
^Ihello test
你会发现只替换了前面的8个空格为 TAB
同样我们可以使用 -t
选项指定 TAB
对齐的空格数。比如下面命令按4个空格进行对齐:
unexpand -t 4 /tmp/test.space |cat -T
^I^Ihello^Itest^I
结果的前面是两个 TAB
,也就是每四个空格转换为了一个 TAB
.
若要将所有的空格全部替换,那么需要明确使用 -a
选项进行转换:
unexpand -a -t 4 /tmp/test.space |cat -T
^I^Ihello^Itest^I
使用git hook实现代码的自动转换
在确定好规范使用SPACE或TAB后,我们可以借助git的pre-commit hook来让我们在代码提交前自动进行规范化的转换。
比如,假设我们定义的规范是只使用 SPACE
规范,那么我们可以创建下面的 pre-commit hook
if git rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else # Initial commit: diff against an empty tree object against=$(git hash-object -t tree /dev/null) fi # Redirect output to stderr. exec 1>&2 TMPFILE=$(mktemp) trap 'rm -f ${TMPFILE}' EXIT for file in $(git diff --cached --name-only --diff-filter=ACM $against) do # 只对text类文件进行转换 if file "${file}" |grep 'text' 2>&1 >/dev/null;then echo "expanding ${file}" expand -i -t 4 "${file}" > "${TMPFILE}" cp "${TMPFILE}" "${file}" git add "${file}" fi done
将该文件保存为 .git/hooks/pre-commit
,然后添加可执行权限后,每次提交就会对文件进行格式化处理了:
lujun9972:a/ (master U:1 ?:3✗) $ cat -T test ^Ihello ^Itest^I^I lujun9972:a/ (master U:1 ?:3✗) $ git commit -a -m update expanding test [master 88b2f66] update 1 file changed, 1 deletion(-) lujun9972:a/ (master ?:3✗) $ cat -T test hello ^Itest^I^I
然后我们再通过 post-commit
hook 将转换的文件再转换回TAB来:
TMPFILE=$(mktemp) against="HEAD^1" trap 'rm -f ${TMPFILE}' EXIT for file in $(git diff --cached --name-only --diff-filter=ACM $against) do # 只对text类文件进行转换 if file "${file}" |grep 'text' 2>&1 >/dev/null;then echo "unexpanding ${file}" unexpand -t 4 "${file}" > "${TMPFILE}" cp "${TMPFILE}" "${file}" git add "${file}" fi done
类似的,我们还可以通过 post-merge
hook(实现跟post-commit一样) 来将远端仓库中的代码也自动转回 TAB
,
如此一来, TAB
还好者们就可以安心的在本地使用 TAB
,然后由git帮你自动进行 SPACE
的转换了.
Recommend
-
52
在我们的技术讨论群『云和恩墨大讲堂』中,还有日常的微信互动中,经常有朋友会提出一些有趣的小问题,在空闲的时候,我希望能够记录下来,和大家做一点小分享,以点滴的知识,增进一点点对于Oracle的理解,就名之为『微信课堂』吧。
-
44
git-commit-hook configureable git commit hook 1. Install Downlod the binary, put it into a folder of your $PATH (for example. /usr/local/bin). Ensure your user h...
-
46
-
5
记一次用 Git hook 提效 Published on Sep 15, 2020 in Program with 0 comment
-
7
V2EX › git 同步 git hook 有啥优秀实践吗? x97bgt · 7 小时 20 分钟前 via iPhone · 207 次点...
-
6
Git commit without the pre-commit hook ...
-
9
使用 Husky 来管理 git hook Posted on 04/15/2022 by Ein Verne |
-
7
Git Hook to Add Issue Number to Commit Message Posted on 2019, Jun 16 3 mins read When using project management system (...
-
10
A git pre-push hook to run tests on a particular branch when you push 30.09.2022 0 com...
-
3
关于 Tab 与空格之争,暴躁老哥 Linus 又有新指示极客邦科技InfoQ·2024-04-22 07:50Tab 与空格之争是个延续自 Unix 时代的问题。
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK