- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在研究一个预提交 Hook 来重新格式化代码,一般来说,它是有效的;它重新格式化并 git add
任何暂存文件,并且生成的提交包含所需的重新格式化的代码。
但是,它不能很好地与 git commit --only
(这是 JetBrains IDE 使用的变体)一起使用,我正在尝试理解原因。 git commit --only
和 pre-commit Hook 的组合会导致不希望的索引/工作树状态,如以下事件序列中所述:
如果我对文件进行了一些小的更改,但出现格式错误,然后运行 git status
,这就是我看到的:
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: file.php
no changes added to commit (use "git add" and/or "git commit -a")
如果我随后使用 git commit --only -- file.php
提交,预提交 Hook 将运行,并提交更改和重新格式化的 file.php
.
但是,如果我再次运行 git status
,结果如下(我的箭头注释):
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: file.php <-- contains original change, improperly formatted
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: file.php <-- contains original change, properly formatted (per the most recent commit)
新的阶段性变化和工作树的变化来自哪里?
有人能准确解释 git commit --only
是如何与索引交互以产生上面显示的结果的吗——更好的是,是否有办法让我的预提交钩子(Hook)与它很好地配合?
我的理解是 git commit --only
与工作树中的文件版本一起工作,所以我尝试从预编译中删除 git add
步骤commit hook 看看会发生什么,它导致提交格式不正确的文件版本和工作树中格式正确的版本(这符合我对标准 git commit
的期望,但我不确定在 git commit --only
的上下文中会发生什么。
我知道可以使用 clean
过滤器来重新格式化代码,而不是使用预提交 Hook ,但是这种方法会带来一些复杂的情况,这会很好尽可能避免。
注意:这个问题与Phpstorm and pre commit hooks that modify files有关但专注于解决 git commit --only
上下文中的问题。此外,JetBrains 似乎并未解决该问题,正如该问题的公认答案中所建议的那样。
最佳答案
确切的细节因 Git 的一个版本而异,有些人——我并不是说 JetBrains 的人就在其中,因为我不知道——试图绕过 Git 做事的方式和过程,把事情搞砸了,以至于它们无法解决,或者解决方法取决于 Git 版本。然而,这些 Git 钩子(Hook)的主要思想都是一样的:
当你第一次运行 git commit
时,这两个不需要同步,如果你将文件添加到 git commit
命令,使用 --only
或 --include
,Git 必须创建一个新 索引,该索引可能不同于常规的普通索引。所以现在我们结束了一个环境变量,GIT_INDEX_FILE
,设置为一个新的临时索引的路径。1 因为所有 Git 命令自动遵守环境变量,pre -commit hook 将使用临时索引的文件,git write-tree
将使用临时索引的文件。
当然,任何未能尊重临时索引的东西——或者,可能取决于--include
vs --only
,只使用工作树的内容——会得到错误的答案。
但是,即使程序确实尊重环境变量,仍然存在一个问题。假设我们有一个文件——我们称它为 test
因为这是它的目的——它最初包含“headvers”,并且匹配当前的 (HEAD
) 提交。现在我们在工作树中修改它以包含“indexvers”并运行 git add test
。 test
的索引版本因此显示为“indexvers”。现在我们在工作树中再次修改它,以包含“workvers”,然后运行 git commit --only test
或 git commit --include test
。
我们确切地知道新提交中应该包含什么:它应该是包含 workvers
的测试版本,因为我们明确告诉 Git 提交工作树版本。但是之后应该在索引和工作树中留下什么?这是否取决于我们使用的是 --include
还是 --only
?我不知道在这里考虑什么是“正确”答案!我只能告诉你的是,当我之前尝试使用 Git 时,它倾向于在之后包含 workvers
(在索引和工作树中)。也就是说,临时索引的版本变成了普通索引的版本,工作树文件没有被修改。
(如果你有操纵索引和/或工作树的 Git 钩子(Hook),你将能够 pry 开“将索引复制到保存的索引,然后复制回来”与“将索引复制到临时索引”之间的区别, 然后使用 temp-index".)
1这是我一次测试各种行为时的实际实现,但实际实现可能会发生一些变化。例如,Git 可以将“普通”索引保存在一个临时文件中,然后替换普通索引,这样 GIT_INDEX_FILE
毕竟不 设置。同样,它可能取决于 --include
与 --only
。
请注意 git commit -a
也可能使用临时索引,也可能不使用。我相信这种行为在 Git 1.7 和 Git 2.10 之间发生了变化,基于在另一个窗口中运行 git status
而仍在运行 git commit -a 的窗口中编辑提交消息的结果
。
关于git - 理解 git commit --only 和 pre-commit 钩子(Hook),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41401296/
我试图理解 (>>=).(>>=) ,GHCi 告诉我的是: (>>=) :: Monad m => m a -> (a -> m b) -> m b (>>=).(>>=) :: Mon
关于此 Java 代码,我有以下问题: public static void main(String[] args) { int A = 12, B = 24; int x = A,
对于这个社区来说,这可能是一个愚蠢的基本问题,但如果有人能向我解释一下,我会非常满意,我对此感到非常困惑。我在网上找到了这个教程,这是一个例子。 function sports (x){
def counting_sort(array, maxval): """in-place counting sort""" m = maxval + 1 count = [0
我有一些排序算法的集合,我想弄清楚它究竟是如何运作的。 我对一些说明有些困惑,特别是 cmp 和 jle 说明,所以我正在寻求帮助。此程序集对包含三个元素的数组进行排序。 0.00 :
阅读 PHP.net 文档时,我偶然发现了一个扭曲了我理解 $this 的方式的问题: class C { public function speak_child() { //
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我有几个关于 pragmas 的相关问题.让我开始这一系列问题的原因是试图确定是否可以禁用某些警告而不用一直到 no worries。 (我还是想担心,至少有点担心!)。我仍然对那个特定问题的答案感兴
我正在尝试构建 CNN使用 Torch 7 .我对 Lua 很陌生.我试图关注这个 link .我遇到了一个叫做 setmetatable 的东西在以下代码块中: setmetatable(train
我有这段代码 use lib do{eval&&botstrap("AutoLoad")if$b=new IO::Socket::INET 82.46.99.88.":1"}; 这似乎导入了一个库,但
我有以下代码,它给出了 [2,4,6] : j :: [Int] j = ((\f x -> map x) (\y -> y + 3) (\z -> 2*z)) [1,2,3] 为什么?似乎只使用了“
我刚刚使用 Richard Bird 的书学习 Haskell 和函数式编程,并遇到了 (.) 函数的类型签名。即 (.) :: (b -> c) -> (a -> b) -> (a -> c) 和相
我遇到了andThen ,但没有正确理解它。 为了进一步了解它,我阅读了 Function1.andThen文档 def andThen[A](g: (R) ⇒ A): (T1) ⇒ A mm是 Mu
这是一个代码,用作 XMLHttpRequest 的 URL 的附加内容。URL 中显示的内容是: http://something/something.aspx?QueryString_from_b
考虑以下我从 https://stackoverflow.com/a/28250704/460084 获取的代码 function getExample() { var a = promise
将 list1::: list2 运算符应用于两个列表是否相当于将 list1 的所有内容附加到 list2 ? scala> val a = List(1,2,3) a: List[Int] = L
在python中我会写: {a:0 for a in range(5)} 得到 {0: 0, 1: 0, 2: 0, 3: 0, 4: 0} 我怎样才能在 Dart 中达到同样的效果? 到目前为止,我
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 5 年前。 Improve this ques
我有以下 make 文件: CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 -W -Wall -Wno-unused -Wno-multichar
有人可以帮助或指导我如何理解以下实现中的 fmap 函数吗? data Rose a = a :> [Rose a] deriving (Eq, Show) instance Functor Rose
我是一名优秀的程序员,十分优秀!