git 是否有类似 `svn propset svn:keywords` 或 pre-/post-commit 的钩子?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does git have anything like `svn propset svn:keywords` or pre-/post-commit hooks?
提问by Will Robertson
Browsing through the git documentation, I can't see anything analogous to SVN's commit hooks or the "propset" features that can, say, update a version number or copyright notice within a file whenever it is committed to the repository.
浏览 git 文档,我看不到任何类似于 SVN 的提交挂钩或“propset”功能的内容,例如,只要将文件提交到存储库,就可以更新文件中的版本号或版权声明。
Are git users expected to write external scripts for this sort of functionality (which doesn't seem out of the question) or have I just missed something obvious?
git 用户是希望为这种功能编写外部脚本(这似乎不是不可能的)还是我只是错过了一些明显的东西?
Edit: Just to be clear, I'm more interested in, e.g.,
编辑:为了清楚起见,我更感兴趣,例如,
svn propset svn:keywords "Author Date Id Revision" expl3.dtx
where a string like this:
像这样的字符串:
$Id: expl3.dtx 780 2008-08-30 12:32:34Z morten $
is kept up-to-date with the relevant info whenever a commit occurs.
每当发生提交时,都会与相关信息保持同步。
采纳答案by Jordi Bunster
Quoting from the Git FAQ:
引用Git 常见问题解答:
Does git have keyword expansion?
Not recommended. Keyword expansion causes all sorts of strange problems and isn't really useful anyway, especially within the context of an SCM. Outside git you may perform keyword expansion using a script. The Linux kernel export script does this to set the EXTRA_VERSION variable in the Makefile.
See gitattributes(5) if you really want to do this. If your translation is not reversible (eg SCCS keyword expansion) this may be problematic.
git 有关键字扩展吗?
不建议。关键字扩展会导致各种奇怪的问题,而且无论如何都没有真正的用处,尤其是在 SCM 的上下文中。在 git 之外,您可以使用脚本执行关键字扩展。Linux 内核导出脚本执行此操作以设置 Makefile 中的 EXTRA_VERSION 变量。
如果您真的想这样做,请参阅 gitattributes(5)。如果您的翻译不可逆(例如 SCCS 关键字扩展),这可能会出现问题。
回答by emk
I wrote up a fairly complete answerto this elsewhere, with code showing how to do it. A summary:
我在别处写了一个相当完整的答案,代码显示了如何做到这一点。总结:
- You probably don't want to do this. Using
git describeis a reasonable alternative. - If you do need to do this,
$Id$and$Format$are fairly easy. - Anything more advanced will require using
gitattributesand a custom filter. I provide an example implementation of$Date$.
- 你可能不想这样做。使用
git describe是一个合理的选择。 - 如果您确实需要这样做,
$Id$并且$Format$相当容易。 - 任何更高级的东西都需要使用
gitattributes和自定义过滤器。我提供了一个$Date$.
Solutions based on hook functions are generally not helpful, because they make your working copy dirty.
基于钩子函数的解决方案通常没有帮助,因为它们会使您的工作副本变脏。
回答by georg
Git does have pre-commit and post-commit hooks, they are located inside each .git/hooks directory. Just modify the files and chmod them to make them executable.
Git 确实有 pre-commit 和 post-commit 钩子,它们位于每个 .git/hooks 目录中。只需修改文件并对其进行 chmod 即可使它们可执行。
回答by superk
Although an age-old Q&A. I thought I'd throw one in since this has been bugging me for a long time.
虽然是一个古老的问答。我想我会扔一个进去,因为这已经困扰了我很长时间。
I am used to list the files in a directory by reverse-time order (funny me, heh?). The reason is that I would like to see which files I have (or anyone else has) changed recently.
我习惯于按逆时顺序列出目录中的文件(我很有趣,呵呵?)。原因是我想查看我(或其他任何人)最近更改了哪些文件。
Git will mess my plans because when switching a branch the local repo will completely overwrite the tracked files from the (incremental... I know...) copies that sit in the packed local repo.
Git 会搞乱我的计划,因为当切换一个分支时,本地存储库将完全覆盖位于打包的本地存储库中的(增量......我知道......)副本中的跟踪文件。
This way all files that were checked out will carry the time stamp of the checkout and will not reflect their last modification time..... How so annoying.
这样所有被签出的文件都会带有签出的时间戳,并且不会反映他们最后修改的时间.....真烦人。
So, I've devised a one-liner in bash that will update a $Date:$ property inside any file WITH THE TIME OF LAST MODIFICATION ACCORDING TO WHAT IT HAS ON FILE SYSTEMsuch that I will have an immediate status telling of last modification without having to browse the git log, git showor any other tool that gives the commit times in blamemode.
所以,我在 bash 中设计了一个单行程序,它将更新任何文件中的 $Date:$ 属性,根据文件系统上的最后修改时间,这样我就可以立即获得上次修改的状态无需浏览git log, git show或任何其他工具,在指责模式下提供提交时间。
The following procedure will modify the $Date: $ keyword only in tracked files that are going to be committed to the repo. It uses git diff --name-onlywhich will list files that were modified, and nothing else....
以下过程将修改 $Date: $ 关键字仅在将要提交到 repo 的跟踪文件中。它使用git diff --name-onlywhich 将列出被修改的文件,没有别的......
I use this one-liner manually before committing the code. One thing though is that I have to navigate to the repo's root directory before applying this.
我在提交代码之前手动使用这个单行。但有一件事是我必须在应用它之前导航到 repo 的根目录。
Here's the code variant for Linux (pasted as a multi-line for readability)
这是 Linux 的代码变体(粘贴为多行以提高可读性)
git diff --name-only | xargs stat -c "%n %Y" 2>/dev/null | \
perl -pe 's/[^[:ascii:]]//g;' | while read l; do \
set -- $l; f=; shift; d=$*; modif=`date -d "@$d"`; \
perl -i.bak -pe 's/$Date: [\w \d\/:,.)(+-]*$/$Date: '"$modif"'$/i' $f; \
git add $f; done
and OSX
和 OSX
git diff --name-only | xargs stat -f "%N %Sm" | while read l; do \
set -- $l; f=; shift; d=$*; modif=`date -j -f "%b %d %T %Y" "$d"`; \
perl -i.bak -pe 's/$Date: [\w \d\/:,.)(+-]*$/$Date: '"$modif"'$/i' $f; \
git add $f; done
回答by James A. Rosen
Perhaps the most common SVN property, 'svn:ignore' is done through the .gitignore file, rather than metadata. I'm afraid I don't have anything more helpful for the other kinds of metadata.
也许最常见的 SVN 属性“svn:ignore”是通过 .gitignore 文件完成的,而不是元数据。恐怕我对其他类型的元数据没有任何帮助。

