git checkout 到临时工作树,不更改索引

git checkout to temp work tree without altering index

提问人:kael 提问时间:7/19/2018 更新时间:7/19/2018 访问量:343

问:

我正在创建一个 git 钩子,以确保我在分支之间移动时我的数据库状态是一致的,但我遇到了一个特殊的问题。post-checkout

为此,我必须从“from”分支和“to”分支访问迁移。钩子在索引和工作树与“to”分支同步后运行。它的作用是这样的:post-checkout

  1. 运行以将“from”分支的数据库文件放入 中。GIT_WORK_TREE=/tmp/from-branch git checkout $from_branch -- db/tmp/from-branch/db
  2. 运行以将 “to” 分支的数据库文件放入 中。GIT_WORK_TREE=/tmp/to-branch git checkout $to_branch -- db/tmp/to-branch
  3. 查找迁移中的共同祖先。
  4. 从 运行必要的向下迁移。/tmp/from-branch
  5. 从存储库中的当前工作树运行任何新的向上迁移。

这一切都运行得非常出色,只是在它运行后,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

这两个文件是从 tmp 工作树中检出的文件。Git 似乎假设我将它们签入我的存储库(尽管我将变量设置为另一个路径)并自动将它们作为“暂存”添加到索引中。我已经梳理了手册页以寻找可以防止这种情况的选项,但没有找到任何选项。$from_branchGIT_WORK_TREEgit-checkout

我目前最好的解决方案是在结账后运行,但这感觉像是一个黑客。只是想知道是否有其他人能想到一些更好的解决方案。git reset

git

评论


答:

4赞 torek 7/19/2018 #1

您的术语有点偏离,但这基本上是正确的:先将文件复制到索引中,然后再将它们复制到工作树中。这就是索引索引或缓存工作树的方式,因此名称为索引缓存。(Git 还使用索引的缓存信息来最大程度地减少实际完成的工作量,因此,如果文件已经以正确的形式存在于工作树中,则 Git 不必在那里接触它们。git checkout

正如您所指出的,您正在使用一个不同的、暂时覆盖的工作树。因此,您需要的是一个不同的、暂时覆盖的索引。事实上,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