2012-01-26 68 views
3

我刚刚意识到我遗漏了一个文件,我应该添加到一个提交像5提交。在提交信息中,我说包含了该文件,并且我不想用文本“Oops忘记在提交#XXXXX中添加此文件”进行新的提交“如何编辑以前的git commit?

编辑以前的最佳方式是什么提交,所以我可以添加文件?

回答

8

提交您的修复,然后使用git rebase --interactive重新排序您的提交并将两个提交压缩在一起。详情请参阅the git book

请注意,如果这些提交已经被推到一些地方,那么这样做是不好的主意,因为您将更改存储库历史记录。

一个例子会话看起来是这样的:

% git init 
Initialized empty Git repository in /home/user/repo/.git/ 
% echo "A line" > a.txt 
% echo "A line" > b.txt 
% git add a.txt b.txt 
% git commit -m "Initial commit" 
[master (root-commit) c6329d0] Initial commit 
2 files changed, 2 insertions(+), 0 deletions(-) 
create mode 100644 a.txt 
create mode 100644 b.txt 

你不完整的承诺:

% echo "Another line" >> a.txt 
% git add a.txt 
% git commit -m "Important changes" 
[master 0d28cfa] Important changes 
1 files changed, 1 insertions(+), 0 deletions(-) 
其他一些

承诺:

% echo "Yet another line" >> b.txt 
% git add b.txt 
% git commit -m "Other changes" 
[master 96a092d] Other changes 
1 files changed, 1 insertions(+), 0 deletions(-) 

注意,你已经忘记了财产以后:

% echo "Important line forgotten previously" >> a.txt 
% git add a.txt 
% git commit -m "Oops" 
[master 9dce889] Oops 
1 files changed, 1 insertions(+), 0 deletions(-) 

修复历史与git rebase -i

% git rebase -i HEAD~3 

您将投入你所选择的编辑器类似以下内容:

pick 0d28cfa Important changes 
pick 96a092d Other changes 
pick 9dce889 Oops 

更改它,以便“糟糕”承诺是移动了上面的一行并将pick更改为squash(或只是s)以将其与前面的提交结合:

pick 0d28cfa Important changes 
s 9dce889 Oops 
pick 96a092d Other changes 

然后保存文件并退出编辑。这将弹出另一个编辑器,您可以在其中编辑组合提交的提交消息。它看起来是这样的:

# This is a combination of 2 commits. 
# The first commit's message is: 

Important changes 

# This is the 2nd commit message: 

Oops 

改变它,你觉得是适当的,然后保存并退出。

最后,检查新的承诺确实是两次提交的组合:

% git log -p HEAD~2..HEAD~1 
commit 7a4c496956eb269c551bbf027db8b0f2320b65e4 
Author: User Name <[email protected]> 
Date: Fri Feb 3 22:57:31 2012 +0100 

    Important changes 

diff --git a/a.txt b/a.txt 
index 8d7158c..54df739 100644 
--- a/a.txt 
+++ b/a.txt 
@@ -1 +1,3 @@ 
A line 
+Another line 
+Important line forgotten previously 
+0

我想要一个更彻底的解释,甚至可能是一个演练,但我想这是一个起点。 – Hubro 2012-02-03 19:27:51

+0

我已经添加了一个例子,希望它有帮助! – 2012-02-03 22:25:41

1

可以使用git commit --fixup <hash>做出特殊标记提交的即意与合并之前提交其哈希是<hash>。这是添加缺失文件或修改拼写错误等的理想选择。

一旦您完成修复提交,您需要使用git rebase --interactive --autosquash <starting-point>实际上将修复提交合并到<hash>提交中。 的底线应该是<hash>提交之前的历史中的某个点(为简单起见,您可以使用<hash>^)。

历史重写通常需要注意的地方,如果你已经将你的分支发布到其他用户从其他地方取出的地方,如果你重写历史记录,通常会引起很多混乱和合并问题。在这些情况下,推动更正作为新的提交更简单。

注意:git config --global rebase.autosquash true默认开启自动压扁功能,这意味着您不需要再将--autosquash选项传递给rebase interactive命令。这是一个很好的默认设置。

autosquashing的良好walkthough可以在这里找到:https://robots.thoughtbot.com/autosquashing-git-commits

1

为了做这做git squash

// X is the number of commits you wish to edit 
git rebase -i HEAD~X 

一旦壁球你的提交 - 选择要编辑的e或 'R'。

选择挑最新的承诺,以维护它。

enter image description here


另一种选择是使用过滤器分支

这里是你如何得到这些参数,你可以对其进行更新,并与新的值,而不是旧的重新提交。

在这个例子中,我改变了电子邮件,但同样适用于消息。

git filter-branch --commit-filter ' 
    if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ]; 
    then 
      GIT_COMMITTER_NAME="<New Name>"; 
      GIT_AUTHOR_NAME="<New Name>"; 
      GIT_COMMITTER_EMAIL="<New Email>"; 
      GIT_AUTHOR_EMAIL="<New Email>"; 
      git commit-tree "[email protected]"; 
    else 
      git commit-tree "[email protected]"; 
    fi' HEAD `