我有以下提交历史记录:

头部头部~头部~2头部~3

gitcommit--修改当前HEAD提交。但是如何修改HEAD~3?


当前回答

对我来说,这是为了从回购中删除一些凭证。我试着换基,在换基的过程中遇到了一大堆看似无关的冲突——继续。不要费心尝试重新设置自己的基础,在mac上使用名为BFG(brew-install-BFG)的工具。

其他回答

嗯,这个解决方案可能听起来很愚蠢,但在某些情况下可以拯救你。

我的一个朋友刚刚无意中提交了一些非常大的文件(四个自动生成的文件,每个文件的大小在3GB到5GB之间),然后在此基础上提交了一些额外的代码,然后才意识到git推送不再有效的问题!

这些文件已在.gitignore中列出,但在重命名容器文件夹后,它们被暴露并提交了!现在,在上面还有几次代码提交,但推送一直在运行(试图上传GB的数据!),最终由于Github的文件大小限制而失败。

交互式rebase或任何类似的问题是,他们会处理这些巨大的文件,并且会花费很长时间来做任何事情。然而,在CLI中花了将近一个小时后,我们不确定文件(和增量)是否真的从历史中删除了,或者只是不包括在当前提交中。推也不起作用,我的朋友真的卡住了。

因此,我提出的解决方案是:

将当前git文件夹重命名为~/Project old。再次从github克隆git文件夹(到~/Project)。签出到同一分支。手动将文件从~/Project旧文件夹cp-r到~/Project。确保不需要签入的大量文件被mved并正确包含在.gitignore中。还要确保您没有用旧文件夹覆盖最近克隆的~/Project中的.git文件夹。这就是有问题的历史记录的所在!现在查看更改。它应该是所有最近提交的联合,不包括有问题的文件。最后提交更改,这很好。

这个解决方案最大的问题是,它处理手动复制一些文件,并且它将所有最近的提交合并为一个(显然使用了一个新的提交哈希)

最大的好处是,它在每一步中都非常清晰,它适用于大型文件(以及敏感文件),并且不会在历史上留下任何痕迹!

基于文档

修改旧的或多个提交消息的消息

git rebase -i HEAD~3 

上面显示了当前分支上最后3次提交的列表,如果需要更多,请将3更改为其他内容。列表将类似于以下内容:

pick e499d89 Delete CNAME
pick 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

将pick替换为要更改的每个提交消息之前的改写。假设您更改了列表中的第二个提交,您的文件将如下所示:

pick e499d89 Delete CNAME
reword 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

保存并关闭提交列表文件,这将弹出一个新的编辑器,供您更改提交消息、更改提交消息并保存。

最后,强制推行修改后的承诺。

git push --force

要获得非交互式命令,请在PATH中放置包含以下内容的脚本:

#!/bin/sh
#
# git-fixup
# Use staged changes to modify a specified commit
set -e
cmt=$(git rev-parse $1)
git commit --fixup="$cmt"
GIT_EDITOR=true git rebase -i --autosquash "$cmt~1"

使用它,先暂存更改(使用gitadd),然后运行gitfixup<commit to modify>。当然,如果您遇到冲突,它仍然是交互式的。

最好的选择是使用“Interactive rebase命令”。

gitrebase命令非常强大。它允许您编辑提交消息,合并提交,重新排序。。。等每次重新提交时,都会为每个提交创建一个新的SHA无论内容是否更改,都要提交!你应该是使用此命令时要小心,因为它可能具有剧烈的特别是如果你与其他人合作开发人员。他们可能会在你重新设置一些基础。在您强制推送提交后,它们将退出同步,你可能会在混乱的情况下发现。所以要小心!建议在重新定基之前创建一个备份分支,以便当你发现事情失控时,你可以回到以前的状态。

现在如何使用此命令?

git rebase -i <base> 

-我代表“交互式”。请注意,您可以在非交互式模式下执行重新基准。前任:

#interactivly rebase the n commits from the current position, n is a given number(2,3 ...etc)
git rebase -i HEAD~n 

HEAD表示您的当前位置(也可以是分支名称或提交SHA)。~n的意思是“n之前”,因此HEAD~n将是您当前所在的提交之前的“n”个提交列表。

git-rebase有不同的命令,如:

p或pick保持原样。r或reword:保留提交的内容,但更改提交消息。s或squash:将此提交的更改合并到上一次提交中(列表中位于其上方的提交)。等注意:最好让Git与代码编辑器一起工作,以使事情更简单。例如,如果您使用可视化代码,您可以像这样添加git-config--global-core.editor“code--wait”。或者你可以在谷歌中搜索如何将你喜欢的代码编辑器与GIT相关联。

git rebase示例

我想更改最后两次提交,所以我这样处理:

显示当前提交:#这将在一行中显示所有提交$git日志--单行4f3d0c8(HEAD->documentation)docs:添加项目描述和包含的文件“4d95e08文档:添加创建日期和项目标题“eaf7978(origin/master,origin/HEAD,master)初始提交46a5819创建README.md现在我使用gitrebase来更改最后两个提交消息:$git rebase-i头~2它将打开代码编辑器并显示以下内容:pick 4d95e08文档:添加创建日期和项目标题pick 4f3d0c8文档:添加项目描述和包含的文件#将eaf7978..4f3d0c8重新设置为eaf7978(2个命令)##命令:#p,pick<commit>=使用commit#r,reword<commit>=使用commit,但编辑commit消息...因为我想更改这两次提交的提交消息。所以我会用r或reword代替pick。然后保存文件并关闭选项卡。请注意,rebase是在多步骤过程中执行的,因此下一步是更新消息。还请注意,提交按时间顺序显示,因此最后一次提交显示在该提交中,第一次提交显示第一行中,依此类推。更新消息:更新第一条消息:docs:将创建日期和项目标题添加到文档“README.md”#请输入更改的提交消息。行开始#带有“#”的将被忽略,并且空消息将中止提交。...保存并关闭编辑第二条消息docs:将项目描述和包含的文件添加到文档“README.md”#请输入更改的提交消息。行开始#带有“#”的将被忽略,并且空消息将中止提交。...保存并关闭。在重基结束时,您将收到这样的消息:成功重基并更新refs/heads/documentation,这意味着您成功了。您可以显示更改:5dff827(HEAD->documentation)文档:将项目描述和包含的文件添加到文档“README.md”4585c68文档:将创建日期和项目标题添加到文档“README.md”eaf7978(origin/master,origin/HEAD,master)初始提交46a5819创建README.md我希望这可以帮助新用户:)。

使用git-rebase。例如,要修改提交bbc643cd,请运行:

$ git rebase --interactive 'bbc643cd^'

请注意命令末尾的插入符号^,因为您实际上需要在要修改的提交之前重新返回提交。

在默认编辑器中,在提到bbc643cd的行中修改pick以进行编辑。

保存文件并退出。git将解释并自动执行文件中的命令。您将发现自己处于之前创建提交bbc643cd的情况。

此时,bbc643cd是您最后一次提交,您可以很容易地修改它。进行更改,然后使用以下命令进行提交:

$ git commit --all --amend --no-edit

之后,使用以下命令返回到上一个HEAD提交:

$ git rebase --continue

警告:请注意,这将更改该提交的SHA-1以及所有子项——换句话说,这将重写从此点开始的历史。如果使用命令gitpush-force进行推送,则可以断开repos。