修改工作目录,并暂时混帐pre-commit钩子集结地 [英] modifying working directory and staging area temporarily in git pre-commit hook

查看:166
本文介绍了修改工作目录,并暂时混帐pre-commit钩子集结地的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是类似于<一的方法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

下面是它的行为方式:


  1. 如果我更改了 DB / ,但还没有上演他们的是,他们被关在工作树不会干扰承诺,感谢藏匿保存--keep指数藏匿流行。好!

  2. 但是,如果我有上演修改 DB / 键,它们被自动覆盖提交,那么用户预期的变化是走了后提交。糟糕!

  1. 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 to stash save --keep-index and stash pop. Good!
  2. 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.


  1. 检查,如果用户已经上演更改 DB / 目录( user_staged = 1 如果是这样)

  2. 藏匿用户的变化,而preserving临时区域

  3. 自动生成 DB / 目录中的内容

  4. 比较 DB / 目录下自动生成的版本上演的版本( auto_changes = 1 ,如果他们不同)

  5. 还原用户的工作目录(模标识的错误托雷克),而preserving的 DB /
  6. 的决定:

    • 如果用户演出和自动生成的 DB / 匹配的一切都好

    • 如果用户演出和自动生成的 DB / 不匹配,中止

    • 如果用户没有上演任何修改 DB / 但也有自动生成的变化,舞台它们并继续,但提醒关于他们在提交信息中

  1. Check if user has staged changes to the db/ directory (user_staged=1 if so)
  2. Stash user changes, while preserving the staging area
  3. Auto-generate the contents of the db/ directory
  4. Compare the staged version of the db/ directory to the auto-generated version (auto_changes=1 if they differ)
  5. Restore the user's working directory (modulo the bug torek identified), while preserving a copy of the auto-generated version of db/
  6. 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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆