修改工作目录,并暂时混帐pre-commit钩子集结地 [英] modifying working directory and staging area temporarily in git pre-commit hook
问题描述
我使用的是类似于<一的方法href=\"http://stackoverflow.com/questions/5518349/using-git-to-track-mysql-schema-some-questions\">this 之一使用pre-commit钩子来跟踪到我的数据库架构更改(以及几元上下的表)。
I'm using an an approach similar to this one to use a pre-commit hook to track changes to my database schema (as well as a few metadata-ish tables).
我想尽量保持我的提交干净,所以我要提交信息中大声警告时,有自动变化正在上演/提交。这里是我的 pre-提交
和 pre-提交-MSG
挂钩:
I like to try to keep my commits clean so I want to be loudly warned in the commit message when there are automatic changes being staged/committed. Here are my pre-commit
and pre-commit-msg
hooks:
git的/钩/ pre-提交
.git/hooks/pre-commit
#!/bin/sh
# Save user changes to db/ (if any)
git diff --quiet db/
user_dirty=$?
[[ $user_dirty > 0 ]] && git stash save --keep-index
# Regenerate db/ automatically
db/save_schema_and_meta_tables.sh
# Were any automatic changes made? If so, commit them but warn about it
git diff --quiet db/
auto_dirty=$?
if [[ $auto_dirty > 0 ]]; then
git add db/
echo "WARNING: automatic changes to db/ added to commit" | tee .git/COMMIT_WARNING
fi
[[ $user_dirty > 0 ]] && git stash pop
exit 0
git的/钩/ prepare提交-MSG
.git/hooks/prepare-commit-msg
#!/bin/sh
msgf=$1
wf=.git/COMMIT_WARNING
if [ -e $wf ]; then
msg=$(<$msgf)
( cat $wf; echo "$msg" ) > $msgf
rm -f $wf
fi
下面是它的行为方式:
- 如果我更改了
DB /
,但还没有上演他们的是,他们被关在工作树不会干扰承诺,感谢藏匿保存--keep指数
和藏匿流行
。好! - 但是,如果我有上演修改
DB /
键,它们被自动覆盖提交,那么用户预期的变化是走了后提交。糟糕!
- If I have made changes to
db/
but haven't staged them yet, they are kept in the working tree without disturbing the commit, thanks tostash save --keep-index
andstash pop
. Good! - However, if I have staged changes to
db/
and they are overwritten by the automatic commit, then the user-intended changes are gone after the commit. Bad!
下面是我会的如以发生:如果有用户上演变为 DB /
,他们不完全匹配自动改变,那么整个事情应该退出。我有很多的麻烦搞清楚如何实现这一点:?我怎么能保存用户所做的阶段性变化,然后看是否自动变化不匹配
Here's what I would like to happen: if there are user-staged changes to db/
and they don't exactly match the automatic changes, then the whole thing should abort. I'm having a lot of trouble figuring out how to implement this: how can I save the staged changes made by the user, then see if the automatic changes don't match?
推荐答案
这不是pretty,它是缓慢的,但有一些@托雷克的建议,我想出了以下内容。
It's not pretty, and it's slow, but with some of @torek's suggestions I came up with the following.
- 检查,如果用户已经上演更改
DB /
目录(user_staged = 1
如果是这样) - 藏匿用户的变化,而preserving临时区域
- 自动生成
DB /
目录中的内容 - 比较
DB /
目录下自动生成的版本上演的版本(auto_changes = 1
,如果他们不同) - 还原用户的工作目录(模标识的错误托雷克),而preserving的
DB /
- 的决定:
- 如果用户演出和自动生成的
DB /
匹配的一切都好 - 如果用户演出和自动生成的
DB /
不匹配,中止 - 如果用户没有上演任何修改
DB /
但也有自动生成的变化,舞台它们并继续,但提醒关于他们在提交信息中
- 如果用户演出和自动生成的
- Check if user has staged changes to the
db/
directory (user_staged=1
if so) - Stash user changes, while preserving the staging area
- Auto-generate the contents of the
db/
directory - Compare the staged version of the
db/
directory to the auto-generated version (auto_changes=1
if they differ) - Restore the user's working directory (modulo the bug torek identified), while preserving a copy of the auto-generated version of
db/
- Decision:
- If user-staged and auto-generated
db/
matched, all is well - If user-staged and auto-generated
db/
didn't match, abort - If user hadn't staged any changes to
db/
but there are auto-generated changes, stage them and continue, but warn about them in the commit message
- If user-staged and auto-generated
的 pre-提交
挂钩code:
The pre-commit
hook code:
# Has user staged changes to db/?
git diff --quiet --staged db/
user_staged=$?
# Stash any user changes in the working tree
old_stash=$(git rev-parse -q --verify refs/stash)
git stash save -q --keep-index
new_stash=$(git rev-parse -q --verify refs/stash)
[[ "$old_stash" != "$new_stash" ]] && stashed=1 || stashed=0
# Automatically regenerate db/
db/save_schema_and_meta_tables.sh
cp -a db db_AUTO
# Compare automatically-generated changes to what the user had already staged
git diff --quiet db/
auto_changes=$?
# Restore user's state
[[ $stashed ]] && git reset --hard -q && git stash apply --index -q && git stash drop -q
# abort: if user had staged changes to db/, and automatic changes would overwrite them
# add but warn: automatic changes added, but no user changes to db/
# silent: no user-staged changes, no automatic changes
if (( $auto_changes > 0 )); then
if (( $user_staged > 0 )); then
echo "ERROR: automatic changes to db/ conflict with staged changes"
rm -rf db_AUTO
exit 1
else
rm -rf db/
mv db_AUTO db
git add db/
echo "WARNING: automatic changes to db/ added to commit" | tee .git/COMMIT_WARNING
exit 0
fi
else
rm -rf db_AUTO
fi
这篇关于修改工作目录,并暂时混帐pre-commit钩子集结地的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!