jin5011 发表于 2018-1-13 11:30:05

如何让 Git 忽略掉文件中的特定行内容?

  近期在git遇到几个问题,让我重新认识到git的强大性,下面列出来记录一下
  有一个数据库的配置文件,在用 git add 添加到 index file 时不能透露了相关配置。而如果用 .gitignore 去操作这需求,却会放弃add整个文件,如果这样做的话,commit后其他人就看不到这里面有个config配置文件了,这结果很明显不是我们想要的。怎么做呢?搜索了下要使用git下面的filter配置去过滤那些秘密。官方文档的描述如下:

  filter.driver.clean
  
The command which is used to convert the content of a worktree file to a blob upon checkin. See gitattributes(5) for details.


  filter.driver.smudge
  
The command which is used to convert the content of a blob object to a worktree file upon checkout. See gitattributes(5) for details.



SYNOPSIS
  $GIT_DIR/info/attributes, .gitattributes



DESCRIPTION
  A gitattributes file is a simple text file that gives attributes to pathnames.
  
Each line in gitattributes file is of form:

  

pattern    attr1 attr2 ...  

  文档详情内容请看 git config --help,这里不展开讨论
  这是我当时的一个config.php文件:
<?php  
return array(
  'DB_TYPE'               =>'MySql',            // 数据库类型
  'DB_HOST'               =>'10.66.111.111',    // 服务器地址
  'DB_NAME'               =>'blog',             // 数据库名
  
);
  根据文档的提示,我们应该这么做:
echo config.php filter=rm_conf >> .gitattributes  

  
git config filter.rm_conf.clean &quot;sed 's/\'10\.66\.111\.111\'/\'\'/g;s/\'blog\'/\'\'/g'&quot;
  关于sed的命令的用法及参数说明,点这里
  按照第二条命令运行,再用 git add 添加到 index file 时,发现错误提示
  

sed 's/\'10\.66\.111\.111\'/\'\'/g;s/\'blog\'/\'\'/g': -c: line 0: unexpected EOF while looking for matching `''  
sed 's/\'10\.66\.111\.111\'/\'\'/g;s/\'blog\'/\'\'/g': -c: line 1: syntax error: unexpected end of file
  
error: external filter sed 's/\'10\.66\.111\.111\'/\'\'/g;s/\'blog\'/\'\'/g' failed 1
  
error: external filter sed 's/\'10\.66\.111\.111\'/\'\'/g;s/\'blog\'/\'\'/g' failed
  

  唔...具体哪里错了呢,我们单独在命令行写 sed 's/\'10\.66\.111\.111\'/\'\'/g;s/\'blog\'/\'\'/g' config.php
  命令行打印出了正确的结果
return array(  'DB_TYPE'               =>'MySql',      // 数据库类型
  'DB_HOST'               =>'',             // 服务器地址
  'DB_NAME'               =>'',             // 数据库名
  
);
  一脸懵逼..再仔细查了下git的help文档,发现原来是分号惹的祸

  The syntax is fairly flexible and permissive; whitespaces are mostly ignored. The # and ; characters begin comments to the end of line, blank lines are ignored.

  然后我意识性地在分号前面加了个 \ 转义符,然而还是那个错误。机智的我立马搜 stackoverflow ,不出所料这坑早已有人踩过了,立马找出了答案。以下是链接


[*]Start a git commit message with a hashmark (#)
[*]Escape comment character (#) in git commit messsage
  于是,把commentChar设置为&quot;#&quot;。
git config core.commentChar &quot;#&quot;  
git config filter.rm_conf.clean &quot;sed \&quot;s/'10\.66\.111\.111'/''/g;s/'blog'/''/g\&quot;&quot;
  再run一次,达到了预期的效果!
  but,感觉这样写起来不太美观啊,同一个文件需要隐藏配置项一多起来,就很难看懂这段command了。那我们就把这段脚本放在一个.sh里面,sed分开写,一行一个配置项,这样逻辑就清晰多了。假设这个脚本的名字叫hidden_conf.sh,将这文件放在.git目录里面,如下代码:
!#bin/bash  

  
# filter服务器地址
  
sed -i 's/'10\.66\.111\.111'/''/g' config.php
  
# filter数据库名
  
sed -i &quot;s/'blog'/''/g&quot; config.php
  然后再改下git中config的配置:
git config filter.rm_conf.clean '.git/hidden_conf.sh'
页: [1]
查看完整版本: 如何让 Git 忽略掉文件中的特定行内容?