Git Squash按作者 - 所有作者提交到一个提交 [英] Git Squash by author - All author commits into a single commit
问题描述
我试图将许多提交压缩为一个单独的提交,问题是我需要通过作者(姓名或电子邮件)来完成。
案例: 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屋!