英文:
Workaround a sanity filter on push
问题
- 我在Windows上有一个Git仓库,原始仓库在Linux上。以下情景经常发生:
- 我提交代码到我的仓库
- 我拉取中央仓库的最新更改以进行同步。
- 我尝试推送,但未通过完整性检查。
- 当我修复问题后,仍然无法推送,因为挂钩检查似乎检查每个单独的提交,而不仅仅是最新的代码。
例如,在合并拉取后,我在提交3中解决了以下问题,但推送仍在提交1和2上失败:
remote: [ERR] [user] 文件 xxx.cpp 在提交 abc 中未通过 TrailingWhitespaceTest 测试
remote: [ERR] [user] 文件 xxx.cpp 在提交 xyz 中未通过 TrailingWhitespaceTest 测试
我无法合并1、2和3,因为3与1、2不相邻。我也无法修改原始仓库的挂钩。
非常感谢任何解决方案/变通方法。
谢谢。
英文:
I have a Git repository on Windows, the origin is on Linux. The following scenario occurs quite frequently:
- I commit code to my repository
- I pull the latest changes from the central repository to sync.
- I'm trying to push, but fail a sanity checker.
- When I fix the problem I still cannot push, since the hooked checkers seem to check every separate commit, and not only the most up to date code.
E.g., I fixed the problem below in commit 3 after the pull merge, but push keeps failing on commits 1,2:
remote: [ERR] [user] file xxx.cpp in commit abc failed test TrailingWhitespaceTest
remote: [ERR] [user] file xxx.cpp in commit xyz failed test TrailingWhitespaceTest
I cannot squash 1,2 and 3, since 3 is not adjacent to 1,2. I also cannot modify the origin's hooks.
A solution/workaround would be very appreciated.
Thanks.
答案1
得分: 1
自从这个钩子关注每次你推送的提交,你需要在第一个提交中修复问题,而不是最后一个(或任何其他提交)。你可以使用交互式变基来修复,要么是通过停下来编辑引入问题的第一个提交,要么是像我偏好的那样,在你的分支尖端创建一个新的修复提交。假设你的分支看起来像这样:
X-A-B-C-D-E
假设X
是你分支出来的地方(可能是main
或类似的),提交A
到E
是你的新提交。假设提交B
是引入问题的第一个提交。创建修复提交的方式是:
# 进行修复并暂存
# 创建一个提交:
git commit -m "squash into B" # 这将创建一个新的提交F
# 从X开始交互式变基:
git rebase -i X
# 将底部的提交(F)移动到B和C之间,并使用“s”或“f”
# 请注意,在这种情况下,使用“f”可能足够,因为这是一个空格问题,你可能不需要编辑提交消息。
# 保存并退出
如果问题只是空格,那么变基很可能会继续进行而不会产生冲突。但如果后续的提交修改了相同的行,你将不得不在进行变基时解决冲突。
由于上述步骤非常常见,Git提供了交互式变基的内置助手选项:
# 进行修复并暂存
# 创建一个提交:
git commit -m "squash into B" --fixup <commit-id-of-B>
# 从X开始交互式变基:
git rebase -i X --autosquash
# 保存并退出
--autosquash
仅仅查找特定命名的提交消息,并自动在交互式变基的TODO列表中重新排列提交。
旁注: 如果可能的话,获取一个本地的钩子副本可能会有帮助,这样在创建提交时会收到警告。
英文:
Since the hook is looking at each commit you're pushing, you need to fix the problem in the first commit rather than the last one (or any other commit). You can use an interactive rebase to fix, either by stopping for editing the first commit that introduced the problem, or, my preference is to create a new fixup commit on the tip of your branch with the change. Suppose your branch looks like this:
X-A-B-C-D-E
Assume X
is where you branched from (perhaps main
or similar), and commits A
through E
are your new commits. Let's suppose commit B
is the first commit that introduced the issue. The way to create a fixup commit is:
# make the fix and stage it
# create a commit:
git commit -m "squash into B" # this will create a new commit F
# interactive rebase starting from X:
git rebase -i X
# move the bottom commit (F) up to between B and C, and use either "s" or "f"
# Note in this case "f" is probably sufficient since it's a whitespace issue and
# you probably won't need to edit the commit message.
# save and exit
If the issue is just whitespace, it's likely that the rebase will continue without conflicts. If later commits modified the same lines though, you'll have to resolve the conflicts as you go.
Since the above steps are so common, Git has a built in helper option for rebase:
# make the fix and stage it
# create a commit:
git commit -m "squash into B" --fixup <commit-id-of-B>
# interactive rebase starting from X:
git rebase -i X --autosquash
# save and exit
The --autosquash
simply looks for specially named commit messages and automatically rearranges the commits for you in the interactive rebase TODO list.
Side Note: It might be helpful to see if you can get a copy of the hook locally so you are warned when creating your commits.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论