我正在创建一个git post-checkout
钩子,以确保在分支之间移动时我的数据库状态是一致的,但是我遇到了一个特殊的问题。
要使此工作有效,我必须同时访问“ from”分支和“ to”分支的迁移。 post-checkout
挂钩在使用“ to”分支使索引和工作树更新之后运行。它是做什么的:
GIT_WORK_TREE=/tmp/from-branch git checkout $from_branch -- db
,将“ from”分支的db文件放入/tmp/from-branch/db
。GIT_WORK_TREE=/tmp/to-branch git checkout $to_branch -- db
,将“ to”分支的db文件放入/tmp/to-branch
。/tmp/from-branch
运行必要的向下迁移。这一切都很出色,除了运行后,git显示以下内容:
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: db/migrations/non-prod/20180718_102122-new-one-test-data.sql
new file: db/migrations/schema/20180718_102108-new-one.sql
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: db/migrations/non-prod/20180718_102122-new-one-test-data.sql
deleted: db/migrations/schema/20180718_102108-new-one.sql
这两个文件是从$from_branch
检出到tmp工作树中的文件。 Git似乎假设我正在将它们检入到存储库中(尽管将GIT_WORK_TREE
变量设置为另一个路径)并自动将它们作为“暂存”添加到索引中。我对git-checkout
手册页进行了梳理,以查找可以防止这种情况并且没有找到任何选项的选项。
我目前最好的解决方案是在结帐后运行git reset
,但这听起来像是黑客。只是想知道是否还有其他人可以想到更好的解决方案。
答案 0 :(得分:3)
您的术语有点过头,但这在本质上是正确的:git checkout
首先将文件复制到索引中,然后再将其复制到工作树中。索引就是以此方式索引或缓存工作树,因此命名为索引和缓存。 (Git还使用索引的缓存信息来最大程度地减少实际工作量,因此,如果文件已经以正确的形式存在于工作树中,则Git不必在此处进行触摸。)
正如您所注意到的,您正在使用不同临时覆盖的工作树。因此,您需要的是一个不同的,暂时被覆盖的索引。实际上,Git仅支持:
TF=$(mktemp)
trap "rm -f $TF" 0 1 2 3 15 # clean up on exit
rm -f $TF # Git prefers a non-existent file to an empty one
GIT_INDEX_FILE=$TF GIT_WORK_TREE=/tmp/from-branch git checkout $from_branch -- db
rm -f $TF
GIT_INDEX_FILE=$TF GIT_WORK_TREE=/tmp/to-branch git checkout $to_branch -- db
... proceed as before
请注意,如果您选择将/tmp/from-branch
和/tmp/to-branch
工作树保留为永久工作树,则不必每次都删除临时索引,使用两个 permanent 索引来为这两个工作树建立索引。