在Git中提交前暂时清除未跟踪的文件

6
每次我提交代码时,我都担心可能会错过一些依赖项,因此我正在寻找一种最简单的方法,在隔离的环境中测试我的git树,以确保git索引(“staged”)中的任何内容都可以自行编译/运行。我的代码依赖项存在于我执行'git add'的文件系统中,因此简单的编译和运行测试并不能保证如果树(或暂存区)被检出到干净的文件系统上,我所检入的任何内容都可以编译/运行。我可以有一个持续的构建,在提交后进行检查,但我不喜欢历史记录中有任何错误提交,以后必须修补。因此,我想要一种创建隔离环境的方法,其中包括树的检出以及索引/暂存区。我考虑过一件事情,那就是两次使用git stash,即:
1.调用'git stash'保存索引中的文件 2.以某种方式获取未跟踪的文件列表,'git add'所有这些文件,保存一个新的stash 3.删除以前未跟踪的所有文件 4.恢复原始的stash 5.现在我应该有一个干净的环境,其中只有已经检入的代码和我可以编译和测试的暂存区中的代码。 6.完成后,我恢复未跟踪文件的stash,然后取消跟踪它们,以便回到最初的状态。
(这些未跟踪的文件可能有用,但不一定是我想要检入存储库的东西-例如eclipse项目)。我感觉我正在为一个简单的问题过度设计。

1
如果您不想永久删除未跟踪的文件,可以通过克隆存储库来强制执行。您可以使用 git ls-files --others 命令获取未跟踪文件列表。如果这是暂时的,您可以随时使用 git add 命令添加它们,然后删除文件,测试,再使用 git checkout 命令(从索引中复制),最后使用 git reset HEAD 命令将它们从索引中清除。 - Cascabel
3个回答

3
安装这个脚本(或类似的脚本 - 我的也是被盗的)作为一个 pre-commit hook。它会将索引文件复制到临时工作目录并在那里运行构建。它可以捕捉你错过的文件。
我知道至少有一两个其他的 SO 问题解决了这个确切的问题 - 在 pre-commit hook 中测试/验证索引而不是工作目录 - 但我现在找不到它们。
(为了完整起见,我在我的 repo 中将这个脚本命名为 .git-hooks/pre-commit/test-the-index;还有其他几个脚本。请参见下面我用作 .git/hooks/pre-commit 的内容。)
#!/bin/sh
#
# Via: http://github.com/jwiegley/git-scripts/blob/master/pre-commit.sh
#

if [ ! $(git rev-parse --symbolic-full-name HEAD) = refs/heads/master ]; then
    exit 0
fi

# These are the locations I keep my temporary source and build trees in
TMPDIR=$HOME/code/myproject-pre-commit
MIRROR=$HOME/code/myproject-pre-commit-mirror

# Exit with status 1 if any command below fails
set -e

# Checkout a copy of the current index into MIRROR
git checkout-index --prefix=$MIRROR/ -af

# Remove files from MIRROR which are no longer present in the index
git diff-index --cached --name-only --diff-filter=D -z HEAD | \
    (cd $MIRROR && xargs -0 rm -f --)

# Copy only _changed files_ from MIRROR to TMPDIR, without copying timestamps.
# This includes copying over new files, and deleting removed ones.  This way,
# "make check" will only rebuild what is necessary to validate the commit.
rsync -rlpgoDOc --delete --exclude-from=.git-hooks/excludes $MIRROR/ $TMPDIR/

# Everything else happens in the temporary build tree
cd $TMPDIR

nosetests

exit 0

这是我的实际 .git/hooks/pre-commit 文件:
#!/bin/bash

set -e
for hook in $(find .git-hooks/pre-commit -perm /u+x,g+x,o+x -type f -not -name '*~' 2>/dev/null)
do
  echo "@@ Running hook: $(basename $hook)"
  $hook "$@"
done

这是一篇博客文章,提供了我上面回答中第一个脚本的动机。点击此处阅读 - bstpierre
谢谢,这是一个很好的答案!我也试图找到关于此问题的现有SO查询,但没有找到。请问有人可以评论(甚至回答)并提供已经提出此问题的链接吗? - Ash
@AshirusNW - 我可能在这个话题上看到了其他的SO问题,但我可能只是看到了上面链接的博客文章和一两篇类似的帖子。 - bstpierre

3
在测试之前使用 git stash -u --keep-index,在测试完成后使用 git stash pop

哇,这是一个如此简单易懂的答案!谢谢!我刚刚尝试了一下,唯一奇怪的事情是在执行 git stash pop 时更改被添加到了索引中,所以我不得不执行 git reset HEAD 将它们从那里移除并回到原始状态... 奇怪。 - deivid

0

为重要文件设置忽略并简单地删除不重要的文件 git clean -df


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接