Git:如何在预提交挂钩中重新启动暂存文件

tzi*_*tzi 10 git githooks git-stage

我正在写一个git pre-commit钩子.
该脚本可以重新格式化一些代码,因此它可以修改分阶段文件.

如何重新暂存已经上演的所有文件?

tzi*_*tzi 11

如果没有pre-commit hook上下文,您可以使用以下命令获取暂存文件的列表:

git diff --name-only --cached
Run Code Online (Sandbox Code Playgroud)

因此,如果要重新索引分阶段文件,可以使用:

git diff --name-only --cached | xargs -l git add
Run Code Online (Sandbox Code Playgroud)

pre-commit hook上下文中,您应该遵循David Winterbottom的建议,并在其他任何事情之前存储未分级的更改.

此技术使您不必担心索引或更改未暂存的更改.因此,您不必暂存所有已暂存的文件,而是所有已更新的文件:

# Stash unstaged changes
git stash -q --keep-index

# Edit your project files here
...

# Stage updated files
git add -u

# Re-apply original unstaged changes
git stash pop -q
Run Code Online (Sandbox Code Playgroud)

  • 对我不起作用...当我“隐藏”时,它还会添加暂存文件。因此它正确地添加更新的文件来提交,但是当我执行“stash pop”时,它将以前的版本放回我的工作目录 (2认同)

Nov*_*e C 9

我喜欢@ tzi的回答; 然而,在David Winterbottom的引文中,在评论中提出了一个边缘案例问题,你将失去一些提交历史.尽管如此,它并不像评论者所说的那样悲惨和悲观,对于有问题的人来说,这又是一个边缘案例.它发生在

  1. 您暂存文件(版本A)
  2. 提交前编辑同一文件(版本B)
  3. 希望提交原始暂存的文件(版本A)而不是修改后的文件(版本B)

如果您的提交失败,或者在提交之前成功并弹出存储,则会丢失原始暂存的文件(v.A),因为它从未提交并被覆盖(使用v.B).显然不是灾难性的,你仍然有最新的编辑(v.B),但它可能会妨碍一些人的工作流程和(次优的)提交实践.为了避免这种情况,您只需检查脚本的退出并使用一些存储技巧恢复到原始状态(索引具有v.A且WD具有v.B).

预提交

#!/bin/sh

... # other pre-commit tasks

## Stash unstaged changes, but keep the current index
### Modified files in WD should be those of INDEX (v. A), everything else HEAD
### Stashed was the WD of the original state (v. B)

git stash save -q --keep-index "current wd"

## script for editing project files
### This is editing your original staged files version (v. A), since this is your WD 
### (call changed files v. A')

./your_script.sh

## Check for exit errors of your_script.sh; on errors revert to original state 
## (index has v. A and WD has v. B)

RESULT=$?
if [ $RESULT -ne 0 ]; then
git stash save -q "original index"
git stash apply -q --index stash@{1}
git stash drop -q; git stash drop -q
fi
[ $RESULT -ne 0 ] && exit 1

## Stage your_script.sh modified files (v. A')

git add -u
Run Code Online (Sandbox Code Playgroud)

您还应该移动git stash pop到提交后挂钩,因为这是在提交之前用修改后的文件(v.B)覆盖暂存文件(v.A)的内容.在实践中,您的脚本很可能不会失败,但即使这样,您git stash pop在预提交挂钩中也会与脚本修改的文件(v.A')和未分阶段的修改(v.B)产生合并冲突.这样就可以防止文件被提交了,但你确实修改了你的脚本最初分阶段文件(v.A')和你的非分段后分段修改文件(v.B)(假设your_script.sh只是假设没有丢失任何重要的历史记录)诸如缩进之类的东西所以v.A和v.A'几乎相同).

简介:如果您在再次修改之前使用最佳实践并提交暂存文件,则原始答案最简单,最好.在我看来,如果你有不这样做的坏习惯,并且想要你的历史中的两个版本(分阶段和修改过),你需要小心(为什么这是一个不好的做法的争论)!无论如何,这可能是一个可能的安全网.