我们正在转换一个项目,用SASS替换一些CSS文件。
在使用.scss
文件进行开发期间,.css
文件会自动生成,但我们不希望在存储库中提交这些文件。
假设我们有一个名为loginModule
的模块,它位于文件夹login
中。在login
内,我们目前有两个CSS文件:login.css
和ux-theme.css
。我想将login.css
替换为login.scss
。在推送我的代码时,如果login.css
存在,我将无法推送login.scss
。
确保同一目录中不存在具有相同名称的.scss
和.css
文件的最佳方法是什么?
答案 0 :(得分:1)
您已经具体询问了服务器端挂钩,即预接收或更新挂钩,但当然,此处至少有两个方面:服务器和客户端。在客户端上,作业是或者至少可以更容易,因为您可以处理普通文件系统中的普通文件。 (目前只有)其他answer by 0.sh执行此类操作,但不是作为挂钩,甚至不使用任何实际的Git命令:它只添加.gitignore
条目,如果已经跟踪了文件,无论如何,这些参赛作品都没有用。
我将解决您提出的服务器端问题,因为服务器是唯一的位置,您可以强制执行完全禁止。问题是预接收和更新挂钩难以编写。
无论你选择哪种钩子,都要记住在命令行中使用参数或stdin上的一系列输入行调用,为你提供 ref-name (对于{{1一个引用,作为参数)或完整的引用集(update
:所有refs,作为输入流)要更新。您的工作是验证您是否同意建议的更新,如果是,则退出为零状态,否则退出非零状态。
我在this sample that checks for merge commits的预接收挂钩中说明了这样做的机制。在您的情况下,您可能会执行类似的操作,但替换函数pre-receive
,以便检查添加的提交而不是检查合并。 内容。还要记住修改check_branch_add_commits
以处理"删除一些提交,添加其他提交"案件也在这里。当一些提交被删除时,它们在check_branch_update
的输出中;当添加一些提交时,它们位于git rev-list $NEW..$OLD
的输出中。 (由于git rev-list $OLD..$NEW
检查了这些,你可以简单地在所有情况下调用它。)
接下来,为了检查添加的提交,您必须逐个遍历它们:
check_branch_add_commits
其中local rev
for rev in $(git rev-list $OLD..$NEW); do
check_one_commit $rev
done
检查指定的提交。
您的测试归结为"如果名称 .scss存在,则禁止现有" 名称 .css在某些(所有?)目录集中,因此check_one_rev_commit
必须检查指定的提交(check_one_commit
将是其哈希)。这个命令:
$1
生成提交中每个文件的列表。只列出带有嵌入空格的文件名,但如果文件名具有嵌入的换行符,则会对其进行编码:
git ls-tree -r --name-only $1
您可能希望以不同方式处理此问题,或在编写程序以阅读名称时使用$ git ls-tree -r --name-only HEAD
foo
has * star
"has a \nnewline"
name with a space
选项。
接下来,您必须编写一个程序来读取名称。 : - )
这个程序会相当复杂。你确实得到了一个很好的保证:每个子目录中的所有名称都将是" clustered"进入该目录,例如,这是来自真实存储库的部分-z
:
git ls-tree -r --name-only
这里的两个子目录是rfuncs.c
rfuncs.h
sbuf/sbuf.c
sbuf/sbuf.h
transport/socket.c
transport/socket.h
utils.c
和sbuf
,正如您所看到的,它们列在所有" r" -named文件之后和任何&#34之前; u" - 已命名的文件,按排序顺序。
然后,如果没有包含任何transport
文件且包含相应*.scss
的目录,那么您的程序任务将从stdin读取文件列表并退出0(成功)文件,如果有,则为非零。 (如果使用*.css
,则可以读取每个ASCII NUL字符。)然后,您可以执行此操作:
-z
您的检查程序可能会打印 提交错误的原因(即scss和css文件的完整路径名冲突)。
编写这个程序还有一件小事,但我把它留给你。如果您的程序读取标准输入,则很容易测试:只需准备一份"建议的if git ls-tree -r --name-only -z $rev | /path/to/program/to/check; then
# do nothing, this commit is OK
else
echo "bad commit found at $rev"
STATUS=1 # assuming my general framework
fi
输出列表"并在每一个上运行它,确保它拒绝该树或接受它,这取决于该树是否符合您的特定标准。
答案 1 :(得分:0)
如果我非常理解您的问题,如果login.scss
存在于login.css
所在的同一目录中,则您不想推login.scss
。你必须编写这个脚本。也许这就是你想要的我不知道的。
#!/bin/bash
checkIfFileMatch() {
file=${1}
if [[ ! -f $file ]];then
echo "$file not found in $(pwd)"
return 2
fi
filename=${file%.*}
for i in *;do
remExt=${i%.*}
if [[ $remExt != $filename ]];then
printf "%s\n" "$i" >> .gitignore
fi
done
}
checkIfFileMatch "login.scss"
您必须将单个文件传递给checkIfFileMatch
。
脚本的作用是,它需要一个争论并检查文件是否存在于当前工作目录中,然后删除文件扩展名。在for循环*
中列出了当前工作目录中的所有文件。 if语句检查传递给checkIfFileMatch
的文件名是否等于循环中的任何文件。运行此脚本,其中包含scss文件。在>> .gitignore
所在的位置,将其替换为您git init
所在的目录>> /root/MyProject/App/.gitignore