使用空提交消息重新发布git历史记录

时间:2011-12-17 03:14:45

标签: git

我最近使用git svn转换了一个svn存储库。不幸的是,svn历史记录有许多空提交消息。当我在没有提交消息的最近提交之前重新定义和编辑/重新提交提交时,这是一个问题。

$ git rebase -i d01
[detached HEAD ff9839c] asdf
 2 files changed, 9 insertions(+), 0 deletions(-)
Aborting commit due to empty commit message.
Could not apply 054e890... 

$ git branch
* (no branch)
  master

$ git commit --amend
fatal: You are in the middle of a cherry-pick -- cannot amend.

在这个例子中,我为第二次最近一次提交提交了一条提交消息,提交了一个空提交消息,并且在最近一次提交时使用空提交消息停止了优化。

我想一次编辑所有带有空消息的提交。有没有办法可以做到这一点?也许我可以使用空提交消息更改所有提交以使提交消息首先“空”?

6 个答案:

答案 0 :(得分:13)

要使用某个模板替换空提交消息,您可以执行以下操作:

git filter-branch -f --msg-filter '
read msg
if [ -n "$msg" ] ; then
    echo "$msg"
else
    echo "The commit message was empty"
fi'

答案 1 :(得分:10)

正如我之前评论的那样,如果您碰巧在其中添加换行符,则会完全破坏评论。这是一个perl脚本,可以做到这一点,而不是破坏性的:

#!/usr/bin/perl

my $data = "";    
while(<STDIN>) {
    $data .= $_;
}

if($data =~ /^\s*$/) { $data="[Empty message]\n"; }
print "$data";

然后,只需git filter-branch -f --msg-filter /path/to/perlfilter.pl

答案 2 :(得分:3)

如果您有多行,您也可以使用cat:

git filter-branch -f --msg-filter \
 'msg=$(cat); if [ "$msg" = "" ]; then echo "Here was an empty commit message"; else echo "$msg"; fi'

它处理具有多行的提交消息以及包含空行的消息。

答案 3 :(得分:2)

  

由于空提交消息而中止提交。

你不会在Git 2.17(2018年第一季度)中遇到这个问题,因为&#34; git rebase&#34;学会了采取新的选择:&#34; --allow-empty-message&#34;。 (这是Git 2.19中的默认值,见下文)

commit a6c612bGenki Sky (``)(2018年2月4日) (由Junio C Hamano -- gitster --合并于commit 2f6128d,2018年2月21日)

  

rebase:添加--allow-empty-message选项

     

此选项允许重新提交具有空提交消息的提交,   匹配git-commitgit-cherry-pick中的相同选项   虽然空的日志消息不受欢迎,但有时会发现它们更旧   存储库(例如从另一个VCS翻译)或具有其他存储库   希望他们的理由。
  该选项在git-commitgit-cherry-pick中可用,因此很自然地让其他git工具与它们很好地配合使用。
  将此选项添加为选项允许默认为&#34;为用户提供修复&#34;的机会,同时不会中断用户的工作流程。

Elan Ruusamäe确认in the comments

  

就像一个魅力。使用提到的提交构建。 +

git rebase --root HEAD --allow-empty-message 
 Successfully rebased and updated detached HEAD. 

git checkout -B master 

使用Git 2.19(Q8 2018),--allow-empty-message是默认选项:

请参阅commit b00bf1ccommit 1634688commit 0661e49commit 4d34dffcommit 983f464commit c840e1acommit 9929430(2018年6月27日) ,commit d4e8062commit 5dacd4a(2018年6月25日)Elijah Newren (newren) (由Junio C Hamano -- gitster --合并于commit 0ce5a69,2018年7月24日)

git-rebase:make --allow-empty-message默认

对于空提交消息,

rebase后端目前的行为方式不同, 很大程度上是作为不同基础命令的副作用 他们是基于。基于am的rebase使用空提交应用提交 消息不停止或要求用户指定额外标志。 (值得注意的是,基于am的rebase是默认的rebase 类型,没有人曾经请求过--no-allow-empty-message标志 改变这种行为。)基于合并和基于交互的rebase(其中 最终基于git-commit),目前将停止任何此类 提交并要求用户手动指定如何处理 提交并继续。

  

行为差异的一个可能原因是目的   &#34; am&#34;基于rebase的仅仅是为了移植现有的历史   和#34;互动&#34; rebase是一个目的是之前抛光系列的人   使它可以发布。
  因此,在后一种情况下,停止并要求确认可能的问题更为合适。

     

但是,这个理由有两个问题:

     
      
  • 1)基于合并的rebase也是非交互式的,并且有多种类型的rebase使用交互式机制但没有明确地交互(例如,当指定--rebase-merges--keep-empty时>没有 --interactive)   这些rebase也仅用于移植现有历史记录,因此也应默认为--allow-empty-message
  •   
  • 2)这个理由只表示用户更倾向于在显式交互式rebase的情况下停止,而不是因为这个特殊原因而停止实际上是有意义的。
      探究它是否有意义,需要备份和分析基础命令......
  •   
     

如果git-commit默认情况下没有在空提交时出错,则意外   创建具有空消息的提交将是非常常见的事件   (这张支票多次抓到我)   此外,几乎所有这些空提交消息都将被视为意外错误(由版本控制系统和各种博客文章中的大量文档证明,这些文档解释了提交消息的重要性)。   因此,对一个常见错误进行简单检查非常有意义,git-commit获得了--allow-empty-message标志,用于特殊情况覆盖。
  这使得空信息的提交非常罕见。

     

对于rebase(和。),有两个提交空消息的来源   樱桃采摘):

     
      
  • (a)用户之前在git中创建的提交   指定--allow-empty-message到git-commit,和
  •   
  • (b)提交从其他版本控制系统导入git。
  •   
     

在情况(a)中,用户已经明确指定了这个提交的特殊内容,这使得他们不想指定提交消息;强迫他们重新指定每一个樱桃挑选或变形似乎更有可能是真气而不是有用。

     

在情况(b)中,提交极不可能由导入历史记录并且正在进行改变或挑选的人创作,因此用户不太可能是写一个人的合适人选。为它提交信息   停止并期望用户在继续之前修改提交因此似乎适得其反。

     

此外,请注意,虽然空提交消息是常见的错误情况   git-commit要处理,这是一个极少数情况下的rebase(或cherry-pick)   它很少这一事实提出了为什么它值得的问题   检查和停止这种特殊情况而不是其他情况。

     

例如,为什么交互式rebase不会自动停止   提交消息的第一行是2000列长,或者缺少空白   在第一行之后的行,或者每行用五个空格缩进,或者   还有其他无数的问题吗?

     

最后,请注意,如果执行交互式rebase的用户确实拥有   必要的知识,为任何此类提交添加消息,并希望这样做   因此,他们更改相应的线条非常简单   &#39;摘&#39;改为&#39;   用户编辑的待办事项列表中的主题为空的事实甚至可以作为通知他们的方式。

     

据我所知,基于合并和交互式的事实   使用空提交消息提交的rebase停止仅仅是副产品   基于git-commit   很长一段时间没有通知,正是因为这种情况很少见。这种情况很少见,因此难以推理,所以当人们最终注意到这种行为时,他们认为这是有充分理由的,只是添加了--allow-empty-message标志。   在我看来,在任何这些情况下停止这些消息是不可取的,甚至是(明确的)交互式案例。

注意:&#34; git rebase&#34;在给出空的时候,Git 2.19中没有中止 作为编辑结果提交日志消息,已在Git 2.20(Q4 2018)中更正。

  

sequencer:修复--allow-empty-message行为,让它变得更聪明

     

commit b00bf1c(&#34; git-rebase:make --allow-empty-message   默认&#34;,2018-06-27,Git v2.19.0-rc0),给出了几个参数,用于移植空提交而不停止并要求用户在每次提交时进行确认。

     

这些论点是不完整的,因为逻辑明确假设所考虑的唯一案例是移植带有空消息的提交(请参阅有关&#34的注释;有两个提交空消息的提交源)。

     

它没有讨论甚至考虑用户被明确要求提交新提交消息并提供空提交信息的翻译,南瓜等。
  (我的不好,当时我完全应该考虑过这个问题,但事实并非如此。)

     

然而,如上所述,Rewords和南瓜明显不同   作者:SZEDER:

     
Let's suppose you start an interactive rebase, choose a commit to
squash, save the instruction sheet, rebase fires up your editor, and
then you notice that you mistakenly chose the wrong commit to
squash.  What do you do, how do you abort?

Before [that commit] you could clear the commit message, exit the
editor, and then rebase would say "Aborting commit due to empty
commit message.", and you get to run 'git rebase --abort', and start
over.

But [since that commit, ...] saving the commit message as is would
let rebase continue and create a bunch of unnecessary objects, and
then you would have to use the reflog to return to the pre-rebase
state.
  
     

另外,他说:

     
    

提交消息模板中的说明,显示为&#39; reword&#39;和&#39; squash&#39;也是,仍然说......

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
  
     

这些是在顺控程序操作期间编辑提交消息时的声音参数,如果提交消息为空,则操作应暂停并要求用户更正。
  当使用空提交消息移植先前创建的提交时,提交b00bf1c(上面引用)中的参数仍然适用,因此序列发生器不应该停止那些。

     

此外,到目前为止,所有理由同样适用于樱桃选择   变基。

     

因此,请编写代码:

     
      移植现有提交时
  • 默认为 --allow-empty-message
  •   
  • 默认为暂停,当要求用户编辑提交消息并提供空消息时 - 对于rebase和cherry-pick。
  •   

答案 4 :(得分:0)

你可以使用樱桃选择:

git checkout -b temp_branch master
git checkout
git cherry-pick --allow-empty-message first_commit_to_include^..my_branch
# delete old my_branch and rename temp_branch to my_branch
git branch -D my_branch
git branch -m my_branch

答案 5 :(得分:0)

您可以重新发送并继续提交空提交消息:

Aborting commit due to empty commit message.
Could not apply XXX... XXX
$ git commit --allow-empty -C $(<"$(git rev-parse --git-dir)/rebase-merge/onto")
$ git rebase --continue