我有以下提交历史记录:

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

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


当前回答

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

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

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

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

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

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

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

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

其他回答

如果您还没有推送提交,则可以使用git reset HEAD^[1,2,3,4…]返回到上一次提交

例如

git commit <file1> -m "Updated files 1 and 2"
git commit <file3> -m "Updated file 3"

抱歉,忘记在第一次提交时添加file2。。。

git reset HEAD^1 // because I only need to go back 1 commit

git add <file2>

这将在第一次提交时添加file2。

更改上次提交:

git commit --amend
// or
git commit --amend -m "an updated commit message"

不修改公共承诺修改后的提交实际上是全新的提交,以前的提交将不再位于当前分支上。

例如,如果您想更改最后三个提交消息或该组中的任何一个提交消息,您可以向git rebase-i提供一个参数,该参数是您要编辑的最后一个提交的父级,即HEAD~2^或HEAD~3。记住~3可能更容易,因为您正在尝试编辑最后三次提交,但请记住,您实际上是在指定四次提交之前,即您要编辑的最后一次提交的父级:

$ git rebase -i HEAD~3

了解更多信息

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

自动交互式重新基础编辑,然后提交恢复,以备重做

我发现自己经常修复一个过去的错误,为此我写了一个脚本。

以下是工作流程:

git提交编辑<提交哈希>这将在您要编辑的提交时将您丢弃。修复并按您希望的方式进行提交。(您可能希望使用git存储保存来保存未提交的文件)重新提交--修改,如:修改最后一次提交完成重新基准:git rebase—继续

为了实现上述功能,请将以下脚本放入$PATH中名为gitcommitedit的可执行文件中:

#!/bin/bash

set -euo pipefail

script_name=${0##*/}

warn () { printf '%s: %s\n' "$script_name" "$*" >&2; }
die () { warn "$@"; exit 1; }

[[ $# -ge 2 ]] && die "Expected single commit to edit. Defaults to HEAD~"

# Default to editing the parent of the most recent commit
# The most recent commit can be edited with `git commit --amend`
commit=$(git rev-parse --short "${1:-HEAD~}")
message=$(git log -1 --format='%h %s' "$commit")

if [[ $OSTYPE =~ ^darwin ]]; then
  sed_inplace=(sed -Ei "")
else
  sed_inplace=(sed -Ei)
fi

export GIT_SEQUENCE_EDITOR="${sed_inplace[*]} "' "s/^pick ('"$commit"' .*)/edit \\1/"'
git rebase --quiet --interactive --autostash --autosquash "$commit"~
git reset --quiet @~ "$(git rev-parse --show-toplevel)"  # Reset the cache of the toplevel directory to the previous commit
git commit --quiet --amend --no-edit --allow-empty  #  Commit an empty commit so that that cache diffs are un-reversed

echo
echo "Editing commit: $message" >&2
echo

基于文档

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

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