Git如何签出提交进行一些更改并将其推送回相同的提交

Posted

技术标签:

【中文标题】Git如何签出提交进行一些更改并将其推送回相同的提交【英文标题】:Git how to checkout to a commit make some changes and push it back to the same commit 【发布时间】:2021-12-13 21:56:14 【问题描述】:

我正在开发一个功能分支,比如说 git checkout -b "Cool_Feature_1"。我创建了 4 个带有原子更改的提交,因为更容易查看它们并且它们都被分组,例如“移动文件结构”或“删除一些重复的代码”。

假设在 4 次提交中的 1 次中我移动了一个文件。

工作完成后,我推送了所有更改并创建了一个合并请求。审稿人告诉我在commit 1中更改文件路径,其他看起来不错。

我该怎么做?

我的方法: git log 找出必要的提交

然后git checkout 7c802ef576fbad061c6fefb350fde386e7d09087

再次进行更改

git add .

git commit --amend

但是现在,如果我这样做 git push 我会收到:

git push                                                                                                         
 ✔  10137  18:59:06
fatal: invalid refspec '(HEAD detached from 7c802ef57)'

我到底想做什么 git push -f origin Cool_Feature_1 并仅在该 1 次提交中覆盖该小更改。基本上,我想从已经存在的合并请求中更改 1 个提交。

here 的人建议创建一个新分支,但这对我来说不是一个选择。

【问题讨论】:

【参考方案1】:

如果你的编辑很容易,并且你想重新开始,你可以这样:

git checkout Cool_Feature_1
git reset --hard origin/Cool_Feature_1

现在你有了一个和 gitlab 一样的本地分支

git rebase -i HEAD^^^^^

将启动交互式变基

您将获得最近提交的列表。如果您不将默认编辑器设置为其他内容,它将是vim,如果您不知道如何使用,则很难使用。

那么每次提交之前都会有一个pick。将 pick 更改为 e 以获取您要编辑的提交。然后保存文件并退出编辑器。然后它将在您提交后立即停止。你可以像你说的那样修改它......然后输入git rebase --continue。比你should 拥有的东西就像原始的东西一样,除了那个提交更改。为了确保,请像这样:

git diff origin/Cool_Feature_1

另外,我喜欢使用gitk

gitk Cool_Feature_1 origin/Cool_Feature_1

将并排显示两个历史以及它们的分歧点。

然后,如果您对本地版本的分支感到满意,请按照您在问题中所做的那样强制将其推送到原点。


或者做你所做的:

git checkout 7c802ef576fbad061c6fefb350fde386e7d09087

但现在你处于“失态”状态 - 但没关系。

做出改变

那么您需要获取在您签出之后的所有提交。您可以从原始分支中挑选每个:

git cherry-pick origin/Cool_Feature_1^^
git cherry-pick origin/Cool_Feature_1^
git cherry-pick origin/Cool_Feature_1

^ 表示前一个。所以我在上面放的是最后的 3 次提交。如果您正在编辑最后的第 4 个,请执行此操作。如果您正在编辑倒数第三个,那么只需:

git cherry-pick origin/Cool_Feature_1^
git cherry-pick origin/Cool_Feature_1

然后看看你这样做是否正确:

git diff origin/Cool_Feature_1

另外,我喜欢使用gitk

gitk HEAD origin/Cool_Feature_1

这次本地分支被称为HEAD,因为您检查了该提交。

其实,这样打开gitk,整个过程一直开着,每一步看一遍,真的很有帮助。

如果您很高兴您的本地分支与远程分支相同,除了一个提交更改,然后强制推送它。

由于在这种情况下您没有本地分支,因此可以这样:

git push origin HEAD:Cool_Feature_1 -f

【讨论】:

非常感谢。您对rebase 的提示将我带到了第三个选项,不知道它是否更容易,但对我来说更全面。所以我在我的分支“Cool_Feature_1”上进行了 4 次推送。没有更多更改,git status -> “没有什么可提交的,工作树干净”。我现在做新的更改,提交它们(git commit -m "CF-1: Move files. For real"),运行git rebase -i origin Cool_Feature_1squash 我的新提交,即“CF-1:移动文件。真正的”一个到以前的“CF-1:移动文件” 。”犯罪。我的其他提交(例如“CF-1:重命名变量”,“CF-1:...)保持不变。完美:) 哦,是的 - 组合没有尽头

以上是关于Git如何签出提交进行一些更改并将其推送回相同的提交的主要内容,如果未能解决你的问题,请参考以下文章

签出旧提交并将其设为新提交 [重复]

从旧的 Git 提交中删除私有信息

按文件类型拆分 git 分支或提交

失败的 Xcode Git 合并卡住了

如何通过提交消息搜索 Git 存储库?

使用 GIT 如何将不同提交中的文件签出到新分支中? [复制]