`.git/CHERRY_PICK_HEAD` 在提交时有什么区别?
What difference does `.git/CHERRY_PICK_HEAD` make when committing?
注意: 这是对我之前的 post(现已删除)的改写。改写意在给 post 一个不同的焦点。
运行宁 git cherry-pick
后,git
报告存在冲突。我解决了冲突,然后运行git cherry-pick --continue
。此时,$GIT_EDITOR
弹出一个 COMMIT_EDITMSG
缓冲区,其中预填充了精心挑选的提交的原始消息以及一些附加信息,其中包括警告:
# It looks like you may be committing a cherry-pick.
# If this is not correct, please remove the file
# .git/CHERRY_PICK_HEAD
# and try again.
我检查了如果我 "deleted"(实际上,只是暂时重命名).git/CHERRY_PICK_HEAD
文件会发生什么。这产生的直接外在效果是从我的 git
感知提示中删除 |CHERRY-PICKING
指示。
除了我的提示中的这一变化,以及 COMMIT_EDITMSG
缓冲区中的预填充信息可能存在一些差异之外,使用或不使用 .git/CHERRY_PICK_HEAD
执行提交会有什么不同文件到位了吗?
更准确地说,我试图在这里比较两种情况。
第一种情况,我运行
% git cherry-pick --continue
...并且(忽略前面引用的警告)我照常进行提交。
第二种情况,我运行
% rm .git/CHERRY_PICK_HEAD
% git commit
...并像往常一样继续提交。
(假设我在两种情况下使用相同的提交消息。)
这两种情况的最终结果有何不同?
答案取决于你在做什么。使用 --continue
完成序列 — 但如果序列只是一个 cherry-pick,则根本就不是真正的序列。
然而,无论如何,删除 .git/CHERRY_PICK_HEAD
肯定有一个额外的重要影响:完成 一个冲突的 cherry-pick re-uses 原始提交的 author-name-email-and-date 信息。您始终是任何新提交的提交者,但所有提交都不止一个 person-and-timestamp:每个新提交都有两个条目,一个用于 "committer"(您,刚刚进行提交),另一个用于"author"(无论谁写了原始提交,以及他们何时这样做)。 Cherry-pick 保留原始提交的作者信息。
音序器
git cherry-pick
和git revert
——实际上是同一个命令;仅恢复 "works backwards"——使用 Git 调用的 序列器 。也就是说,您可以一次选择多个提交:
git cherry-pick notthis..that thistoo
挑选所有提交 "after" notthis
,直到并包括 that
,以及一个特定的提交 thistoo
。例如,您可能决定 cherry-pick feature/X
上从 develop
增长的每个提交,加上一个错误修复提交 fix-1234
,用于测试目的:
git checkout master
git checkout -b testbranch
git cherry-pick develop..feature/X fix-1234
无论如何,这里的要点是这可能 cherry-pick 十几个或更多提交,并且在此过程中的某个地方可能存在合并冲突,这需要 git cherry-pick
停止并获得帮助。
旁白:这里的模型——Unix/Linux 命令行——是你在一个叫做 shell 的 command-interpreter 中输入一个命令. shell 将 human-interface 的控制权交给新命令,新命令会保留它直到命令完成并退出。一旦命令退出,命令本身就没有任何痕迹:任何永久都必须保存在文件中。
所以:如果 cherry-pick 必须停止,它如何知道从哪里恢复?答案是将信息保存在文件中。如果您正在 cherry-pick 单个提交,Git 仅保存 CHERRY_PICK_HEAD
文件,该文件记录了正在 cherry-pick 提交的 ID。但是,如果您 cherry-picking 多个 提交,Git 将冲突的提交保存为单个提交, 和 将剩余信息保存在排序目录中(其位置随时间移动了一些)。
运行 git cherry-pick --continue
指示(新的、单独的实例)cherry pick 命令从前一个停止的地方开始。 Git会先给你运行一个git commit
,然后定位排序信息,尽可能多的完成这个序列,在下一次冲突时再次停止,或者完成所有的cherry-picks.
运行 git commit
相反,Git 会注意到 CHERRY_PICK_HEAD
文件并使用它,如您所见。当提交完成时,该命令退出并且不对定序器执行任何操作。如果 是 sequencer 数据遗留,您现在可以 git cherry-pick --continue
: Git 会注意到提交已经完成,只需继续/完成 sequencer 操作。
请注意,您可以使用 git cherry-pick --abort
而不是完成操作。这将终止操作并将事情恢复到开始之前的状态。从 Git 2.19 开始,您可以改为使用 git cherry-pick --quit
停止(a la --abort
)但是 not 将事情恢复到您之前的状态开始了。也就是说,它会停止任何未来的 cherry-picking 操作,而不会撤消您目前所做的操作。 (2.19之前没有这个操作。)
git status
命令现在会注意到是否有正在进行的序列,并报告您正在执行您正在执行的任何操作。 (与 Git 1.7 时代相比,这是一个很大的改进,当时它没有。)
正如我评论的那样,git cherry-pick --quit
也删除了 .git/CHERRY_PICK_HEAD
,但是,此外,消息“如果这不正确,请删除文件 .git/CHERRY_PICK_HEAD
”将随着 Git 2.29(2020 年第 4 季度):更新了对两个伪引用的访问以正确使用引用 API.
见commit b8825ef, commit b6d2558, commit c8e4159, commit 3f9f1ac (21 Aug 2020) by Han-Wen Nienhuys (hanwen
)。
(由 Junio C Hamano -- gitster
-- in commit e699684 合并,2020 年 8 月 31 日)
builtin/commit
: suggest update-ref for pseudoref removal
Signed-off-by: Han-Wen Nienhuys
When pseudorefs move to a different ref storage mechanism, pseudorefs no longer can be removed with 'rm
'.
Instead, suggest a "update-ref -d
" command, which will work regardless of ref storage backend.
新消息会提示:git update-ref -d CHERRY_PICK_HEAD
注意: 这是对我之前的 post(现已删除)的改写。改写意在给 post 一个不同的焦点。
运行宁 git cherry-pick
后,git
报告存在冲突。我解决了冲突,然后运行git cherry-pick --continue
。此时,$GIT_EDITOR
弹出一个 COMMIT_EDITMSG
缓冲区,其中预填充了精心挑选的提交的原始消息以及一些附加信息,其中包括警告:
# It looks like you may be committing a cherry-pick.
# If this is not correct, please remove the file
# .git/CHERRY_PICK_HEAD
# and try again.
我检查了如果我 "deleted"(实际上,只是暂时重命名).git/CHERRY_PICK_HEAD
文件会发生什么。这产生的直接外在效果是从我的 git
感知提示中删除 |CHERRY-PICKING
指示。
除了我的提示中的这一变化,以及 COMMIT_EDITMSG
缓冲区中的预填充信息可能存在一些差异之外,使用或不使用 .git/CHERRY_PICK_HEAD
执行提交会有什么不同文件到位了吗?
更准确地说,我试图在这里比较两种情况。
第一种情况,我运行
% git cherry-pick --continue
...并且(忽略前面引用的警告)我照常进行提交。
第二种情况,我运行
% rm .git/CHERRY_PICK_HEAD
% git commit
...并像往常一样继续提交。
(假设我在两种情况下使用相同的提交消息。)
这两种情况的最终结果有何不同?
答案取决于你在做什么。使用 --continue
完成序列 — 但如果序列只是一个 cherry-pick,则根本就不是真正的序列。
然而,无论如何,删除 .git/CHERRY_PICK_HEAD
肯定有一个额外的重要影响:完成 一个冲突的 cherry-pick re-uses 原始提交的 author-name-email-and-date 信息。您始终是任何新提交的提交者,但所有提交都不止一个 person-and-timestamp:每个新提交都有两个条目,一个用于 "committer"(您,刚刚进行提交),另一个用于"author"(无论谁写了原始提交,以及他们何时这样做)。 Cherry-pick 保留原始提交的作者信息。
音序器
git cherry-pick
和git revert
——实际上是同一个命令;仅恢复 "works backwards"——使用 Git 调用的 序列器 。也就是说,您可以一次选择多个提交:
git cherry-pick notthis..that thistoo
挑选所有提交 "after" notthis
,直到并包括 that
,以及一个特定的提交 thistoo
。例如,您可能决定 cherry-pick feature/X
上从 develop
增长的每个提交,加上一个错误修复提交 fix-1234
,用于测试目的:
git checkout master
git checkout -b testbranch
git cherry-pick develop..feature/X fix-1234
无论如何,这里的要点是这可能 cherry-pick 十几个或更多提交,并且在此过程中的某个地方可能存在合并冲突,这需要 git cherry-pick
停止并获得帮助。
旁白:这里的模型——Unix/Linux 命令行——是你在一个叫做 shell 的 command-interpreter 中输入一个命令. shell 将 human-interface 的控制权交给新命令,新命令会保留它直到命令完成并退出。一旦命令退出,命令本身就没有任何痕迹:任何永久都必须保存在文件中。
所以:如果 cherry-pick 必须停止,它如何知道从哪里恢复?答案是将信息保存在文件中。如果您正在 cherry-pick 单个提交,Git 仅保存 CHERRY_PICK_HEAD
文件,该文件记录了正在 cherry-pick 提交的 ID。但是,如果您 cherry-picking 多个 提交,Git 将冲突的提交保存为单个提交, 和 将剩余信息保存在排序目录中(其位置随时间移动了一些)。
运行 git cherry-pick --continue
指示(新的、单独的实例)cherry pick 命令从前一个停止的地方开始。 Git会先给你运行一个git commit
,然后定位排序信息,尽可能多的完成这个序列,在下一次冲突时再次停止,或者完成所有的cherry-picks.
运行 git commit
相反,Git 会注意到 CHERRY_PICK_HEAD
文件并使用它,如您所见。当提交完成时,该命令退出并且不对定序器执行任何操作。如果 是 sequencer 数据遗留,您现在可以 git cherry-pick --continue
: Git 会注意到提交已经完成,只需继续/完成 sequencer 操作。
请注意,您可以使用 git cherry-pick --abort
而不是完成操作。这将终止操作并将事情恢复到开始之前的状态。从 Git 2.19 开始,您可以改为使用 git cherry-pick --quit
停止(a la --abort
)但是 not 将事情恢复到您之前的状态开始了。也就是说,它会停止任何未来的 cherry-picking 操作,而不会撤消您目前所做的操作。 (2.19之前没有这个操作。)
git status
命令现在会注意到是否有正在进行的序列,并报告您正在执行您正在执行的任何操作。 (与 Git 1.7 时代相比,这是一个很大的改进,当时它没有。)
正如我评论的那样,git cherry-pick --quit
也删除了 .git/CHERRY_PICK_HEAD
,但是,此外,消息“如果这不正确,请删除文件 .git/CHERRY_PICK_HEAD
”将随着 Git 2.29(2020 年第 4 季度):更新了对两个伪引用的访问以正确使用引用 API.
见commit b8825ef, commit b6d2558, commit c8e4159, commit 3f9f1ac (21 Aug 2020) by Han-Wen Nienhuys (hanwen
)。
(由 Junio C Hamano -- gitster
-- in commit e699684 合并,2020 年 8 月 31 日)
builtin/commit
: suggest update-ref for pseudoref removalSigned-off-by: Han-Wen Nienhuys
When pseudorefs move to a different ref storage mechanism, pseudorefs no longer can be removed with '
rm
'.
Instead, suggest a "update-ref -d
" command, which will work regardless of ref storage backend.
新消息会提示:git update-ref -d CHERRY_PICK_HEAD