如何按文件拆分每个提交?
Posted
技术标签:
【中文标题】如何按文件拆分每个提交?【英文标题】:How to split every commit by file? 【发布时间】:2017-04-03 13:52:08 【问题描述】:我知道如何使用git rebase -i
手动拆分提交,但是如何自动按文件拆分分支中的每个提交?
例如,commit A
修改了 3 个文件 f1、f2 和 f3。拆分后有 3 个 commit A-f1、A-f2 和 A-f3。
我想这样做是为了让主要的重写更容易,因为我只需要压缩一些小的提交。
【问题讨论】:
按文件拆分提交并没有什么意义,因为这样您将有许多提交,其中一个文件更改了其接口,但其协作者没有反映该更改。如果您不关心细节,那就错在挤压而不是分裂。 【参考方案1】:脚本
以下脚本按文件拆分HEAD
:
#!/usr/bin/env bash
set -e
SHA=$(git rev-parse --short HEAD)
# Change to repo root directory
cd $(git rev-parse --show-toplevel)
git reset HEAD^
git diff-tree --no-commit-id --name-only -r $SHA | while read -r f; do
git add "$f"
GIT_EDITOR="echo '0a\n$SHA $f\n\n.\nw' | ed -s" git commit -c $SHA
done
生成的提交消息的格式为:
<original SHA> <file name>
<original commit message>
用法
以下假设您可以以git-split
运行上述脚本。
如果要按文件拆分范围内的所有提交,请像这样使用它:
git rebase --interactive --exec git-split <branch>
如果您想在交互式变基期间拆分单个提交,请像这样使用它:
p Commit to split
x git-split
欢迎对脚本进行任何改进。
【讨论】:
有趣的脚本,比我的回答更详细。 +1 @VonC 您的回答很好地概述了该怎么做,让我开始了。总而言之,我更喜欢复制粘贴友好的单行而不是我的脚本,虽然:) 很棒的脚本,只是GIT_EDITOR
行不适合我。我将其更改为 git commit -m "$SHA: $f"
以获得更简单的提交消息,现在脚本运行良好 =3
@Ancurio 很高兴你喜欢这个脚本。你在哪个操作系统上?是否安装了ed
(运行which ed
进行检查)?
@raphinesse yes which ed
积极响应。我在 Fedora 31 上。【参考方案2】:
对于每次提交,您都需要
先到list all files in that commit
git diff-tree --no-commit-id --name-only -r <SHA1>
那么对于每个文件,extract that file
git show <SHA1>:/path/within/repo/to/file
在专用分支的工作树中执行此操作,并为提取的每个文件添加和提交。
然后,您可以通过 commit-file 构建的新提交文件重置当前分支。
【讨论】:
自我说明:这是我在 Stack Overflow 上的 第 16000 个答案(98 个月内),距离15000th answer 不到 6 个月。在此之前14000th answer,1300th answer。 12000th answer; 1100th answer, 10000th answer, 9000th answer, 8000th answer, ...以上是关于如何按文件拆分每个提交?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Git 存储库中按作者计算每个文件路径名的提交次数?
R:具有多个标题的列表-如何按标题拆分(每个标题的行数不等)