Git Squash按作者 - 所有作者提交到一个提交 [英] Git Squash by author - All author commits into a single commit

查看:226
本文介绍了Git Squash按作者 - 所有作者提交到一个提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将许多提交压缩为一个单独的提交,问题是我需要通过作者(姓名或电子邮件)来完成。



案例: p>

假设我有一个叫做feature-a的分支,在这个分支中,我为许多作者提供了许多提交。如何将作者的所有提交(例如电子邮件)压缩为单个提交。我希望能够将所有作者提交合并到master中。



这里有任何帮助吗?



谢谢提前

解决方案

在repo离线时,我需要对不必要的大型存储库进行类似的重写。我采用的方法是使用 GIT_SEQUENCE_EDITOR 来尝试自动化的'交互式'rebase,它覆盖在本答案由@ james-foucar& @pfalcon。



为了使这个工作正常,我发现最好先从被重写的历史记录中删除合并。对于我自己的情况,这是通过使用很多 git rebase --onto 来完成的,这在StackOverflow的其他问题中得到了充分的说明。



我创建了小脚本 generate-similiar-commit-squashes.sh 生成选择& squash 命令,这样连续的类似提交就会被压缩。我使用了author-date-and-shortlog来匹配类似的提交,但你只需要作者(我的要点有一个关于如何使它只匹配作者的评论)。

  $ generate-similiar-commit-squashes.sh> / tmp / git-rebase-todo-list 

输出看起来像

  ... 
pick aaff1c556004539a54a7a33ce2fb859af0c4238c foo@example.com-2015-01-01-Update-head.html
squash aa190ea2323ece42f1cd212041bf61b94d751d5c foo @ example.com-2015-01-01-Update-head.html
pick aab8c98981a8d824d2bc0d5278d59bc1a22cc7b0 foo2@example.com-2015-01-28-Update-_config.yml

存储库还充满了自我恢复,具有相同样式的更新xyz提交消息。当被压扁时,它们导致空的提交。



我合并的提交具有相同的提交消息。 git rebase -i 提供了一个修改后的提交消息,并附加了所有压缩的提交消息,这些消息都是重复的。为了解决这个问题,我使用了这个答案,以从 git rebase 提供的提交消息中删除重复的行。它在一个文件中更好,因为它将被用在一个shell变量中。

  $ echo'print if! $ x {$ _} ++'> /tmp/strip-seen-lines.pl 

现在进行最后一步:

  $ GIT_EDITOR ='perl -i -n -f /tmp/strip-seen-lines.pl'\ 
GIT_SEQUENCE_EDITOR =' cat / tmp / git-rebase-todo-list>'\
git rebase --keep-empty -i $(git rev-list --max-parents = 0 HEAD)

尽管使用 - keep-empty git 通过这个关于空提交的过程抱怨了几次。它会将我转储到控制台,其中包含一个不完整的 git rebase 。要跳过空提交并恢复处理,需要以下两个命令(在我的例子中相当频繁)。

  $ git reset HEAD ^ 
$ GIT_EDITOR ='perl -i -n -f /tmp/strip-seen-lines.pl'git rebase --continue

尽管 - keep-empty ,我发现我在最终的git历史记录中没有空的提交,所以上面的重置已经将它们全部删除。我认为我的git版本2.14.1有问题。处理~100万次提交,在蹩脚的笔记本电脑上花费了超过10分钟。


I am trying squash many commits into a single one, the problem is that I need do that by author (name or email).

The case:

Lets say I have a branch called feature-a, in this branch I have many commits for many authors. How can I squash all commits by author (email for example) into a single commit. I want do that to be able to merge all author commits into master.

Any help here?

Thanks in advance

解决方案

I needed to do a similar rewrite on an unnecessarily large repository while the repo was offline. The approach I took was trying automated 'interactive' rebase using GIT_SEQUENCE_EDITOR which is covered in this answer by @james-foucar & @pfalcon.

For this to work well, I found it better to first remove the merges from the section of the history being rewritten. For my own case, this was done using lots of git rebase --onto which is covered amply in other questions on StackOverflow.

I created a small script generate-similiar-commit-squashes.sh to generate the pick & squash commands so that consecutive similar commits would be squashed. I used author-date-and-shortlog to match similar commits, but you only need author (my gist has a comment about how to make it match only on author).

$ generate-similiar-commit-squashes.sh > /tmp/git-rebase-todo-list

The output looks like

...
pick aaff1c556004539a54a7a33ce2fb859af0c4238c foo@example.com-2015-01-01-Update-head.html
squash aa190ea2323ece42f1cd212041bf61b94d751d5c foo@example.com-2015-01-01-Update-head.html
pick aab8c98981a8d824d2bc0d5278d59bc1a22cc7b0 foo2@example.com-2015-01-28-Update-_config.yml

The repository was also full of self-reverts with the same style 'Update xyz' commit messages. When squashed, they resulted in empty commits.

The commits I was merging had identical commit messages. git rebase -i offers a revised commit message with all squashed commit messages appended, which would have been repetitive. To address that, I used a small perl script from this answer to remove duplicate lines from the commit message offered by git rebase. It is better in a file, as it will be used in a shell variable.

$ echo 'print if ! $x{$_}++' > /tmp/strip-seen-lines.pl

Now for the final step:

$ GIT_EDITOR='perl -i -n -f /tmp/strip-seen-lines.pl ' \
  GIT_SEQUENCE_EDITOR='cat /tmp/git-rebase-todo-list >' \
  git rebase --keep-empty -i $(git rev-list --max-parents=0 HEAD)

Despite using --keep-empty, git complained a few times through this process about empty commits. It would dump me out to the console with an incomplete git rebase. To skip the empty commit and resume processing, the following two commands were needed (rather frequently in my case).

$ git reset HEAD^
$ GIT_EDITOR='perl -i -n -f /tmp/strip-seen-lines.pl ' git rebase --continue

Again despite --keep-empty, I found I had no empty commits in the final git history, so the resets above had removed them all. I assume something is wrong with my git, version 2.14.1 . Processing ~10000 commits like this took just over 10 minutes on a crappy laptop.

这篇关于Git Squash按作者 - 所有作者提交到一个提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆