- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我的团队正在开发一个长期运行的特性分支,现在有数百个提交,现在我需要将它 merge 到 master 中以进行生产发布。
我不希望在该分支中有那么多提交,因为许多提交都是为了修复错误而完成的,并且每次提交只更改几行。
在 Github 的 PR 创建页面上,它限制了显示为 250 的提交。
From Github - "This comparison is big! We’re only showing the most recent 250 commits"
因此,我决定以一种方式压缩历史记录,将作者的一组顺序提交压缩为单个提交。
例如,假设我们有这样的提交:来自作者 A、B、C 和 D 的 A - A - A - B - B - A - C - D - D - B- B -A
然后生成的提交日志将包含 A(3) - B
(2) - A - C - D(2) - B
(2) - A 其中 X`(N ) 是来自作者 X 的 N 次提交的压缩提交。
编辑:我知道这需要一个脚本,我正在寻找相同的脚本。我不想通过交互式 rebase 来做同样的事情。
最佳答案
没有内置的东西可以做到这一点;您将不得不编写自己的脚本。
为此,从 git rev-list
或 git log
开始(两者本质上做同样的事情,但命令行选项略有不同)来遍历所有您要扫描的提交。您的目标是将提交复制但压缩到一个新的临时分支上。例如,假设所有提交都是在分支 feature
上进行的,并且要 merge 到分支 target
中,您可以获得要检查的提交列表:
git rev-list --reverse --topo-order target..feature > /tmp/list
此处的输出是提交 SHA-1 ID 的列表。对于每个提交,您都希望找到作者,可能还有提交消息:
while read sha1; do
author_name=$(git log -n 1 --format=%an $sha1)
...
done < /tmp/list
如果当前作者姓名与之前作者姓名相同,则只想累积本次提交,但如果不同,则需要发出提交 ID。由于 $author_name
最初未设置,它将是空字符串,因此第一次提交不会匹配以前的作者,但你必须特别处理这个(连同最终提交 ID),因为你总是想要累积第一次提交,并在最后一次提交或作者更改后采取行动。因此 ...
部分有点复杂。我们还需要一些设置工作来创建并进入一个临时分支,其第一个提交指向分支 target
的尖端。我们将在此处使用匿名分支,而不是使用命名的临时分支。
最后,压缩提交的方法特别棘手:执行此操作的简单方法是使用管道命令 git commit-tree
,然后推进临时分支。
将所有这些放在一起,我们得到以下完全未经测试的代码:
# add new squash-style commit using commit $1
make_squash_commit() {
local sha1=$1 tree new_sha1
tree=$(git rev-parse $sha1^{tree})
new_sha1=$(git commit-tree $tree -p HEAD)
git update-ref -m "squash $sha1" HEAD $new_sha1
}
set -e
git rev-list --reverse --topo-order target..feature > /tmp/list
git checkout --detach target
: > /tmp/accum_log
prev_sha1=""
while read sha1; do
author_name=$(git log -n 1 --format=%an $sha1)
if [ "$author_name" != "$prev_name" -a -n "$prev_sha1" ]; then
make_squash_commit $prev_sha1 < /tmp/accum_log
: > /tmp/accum_log
fi
prev_name="$author_name"
prev_sha1=$sha1
git log -n 1 --format="%B" $sha1 >> /tmp/accum_log
done < /tmp/list
if [ -z "$prev_sha1" ]; then
echo "Warning: no commits found to squash!"
sha1=$(git rev-parse target)
fi
# squash final commit, then give anonymous branch a name
make_squash_commit $prev_sha1 < /tmp/accum_log
git checkout -b temp_branch
rm /tmp/list /tmp/accum_log
这个脚本中有一个有点故意的缺陷:它使用当前日期和时间(这是合适的,因为你是把多个作者的提交弄得一团糟,不管他们是否同意都压缩它们)。您可以通过在 git commit-tree
步骤中设置所有适当的环境变量来“修复”此问题(请参阅其文档)。
关于Git Squash 作者按顺序提交以压缩历史记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34127596/
在日常工作中,我选择使用 SmartGit 作为客户端。然而,我的团队成员坚持使用 git 原生的非商业 GUI。我们发现我们的 merge 提交看起来有些不同。 这些是 SmartGit 在请求 m
我正在尝试压缩 3 次提交。 我克隆存储库 我用要压缩的提交 checkout 分支 我运行“git rebase -i HEAD~3” 我“选择”最重要的提交,然后“压缩”第二个和第三个提交。这一切
我需要一些帮助来压缩 GitHub 中的提交。 我有大约 30 个提交,我想将前 10 个提交压缩为一个压缩提交,将另外 10 个提交压缩为另一个压缩提交。我使用了 git rebase -i HEA
我有一个大的 docker 镜像 A,我创建了一个新的 Dockerfile FROM A RUN rm /big-folder 我尝试使用以下方法构建图像: docker build --squas
在我的本地开发环境中使用推送部署系统会生成大量提交,我不想将其推送到上游。 我想要一种更快、更自动化的方法来将已自动生成的提交压缩为未自动生成的提交。当我的日志看起来像: > (HEAD -> fea
我有一个尚未发布的本地存储库,其图形结构如下: * G * F |\ | * E | * D * | C: A minor fix -- SQUASHME * | B |/ * A 所以
我见过的所有示例都涉及只有一个提交者的分支。我想要实现的是一个自动 git rebase -i,其中,对于给定的分支.. 给定用户所做的所有提交都将被压缩在一起。 因此,如果 3 个人在一个分支上工作
我的团队正在开发一个长期运行的特性分支,现在有数百个提交,现在我需要将它 merge 到 master 中以进行生产发布。 我不希望在该分支中有那么多提交,因为许多提交都是为了修复错误而完成的,并且每
我的同事(我们在这里称他为 John)和我一起开发一项功能。我们的工作分支如下所示 --o--o--o # this is develop branch \ o--o--o # this i
考虑我有提交 ... -- A -- B -- C 如果我使用 git rebase -i将所有三个提交压缩为一个,我们可以 pick A squash B squash C 我看到了结果提交 A有它
我想在一个分支中间将几个提交压缩在一起,而不修改前后的提交。 我有: A -- B -- C -- D -- E -- F -- G | | m
这个问题在这里已经有了答案: How do I squash two non-consecutive commits? (5 个答案) 关闭 9 年前。 我在 master 分支上有一些非连续的提交
假设我们有一个名为 feature-branch 的功能分支。该分支的开发人员分支获取他们的票,然后打开一个 PR 到 feature-brach。 如果发生以下情况: 开发人员A从feature-b
假设我将文件 A 添加为提交,然后决定删除文件 A。我没有使用 git --amend,而是创建另一个删除文件 A 的提交,我知道这是不好的做法。但是,如果我想使用 git merge --squas
我试图压制迁移。 不幸的是,有太多的循环依赖。 有没有办法重新开始迁移(尽管我的项目已经部署在生产环境中)而不是试图压缩迁移? 我不必担心一些不知名的开发人员使用我的项目,因为它是一个私有(priva
我有一个带有多个提交的开发分支。该分支应 merge 到主分支中。 我也希望主分支提交历史尽可能干净,所以我只想有一个 merge 条目。因此,我执行以下操作: git merge --squash
运行 git merge --squash 时,提交消息包含我正在压缩的所有提交的提交消息,太棒了。然而,由于某种原因,它实际上包含的不仅仅是我正在压缩的提交。 这是我的工作流程: 各种功能分支通常会
运行 git merge --squash 时,提交消息包含我正在压缩的所有提交的提交消息,太棒了。然而,由于某种原因,它实际上包含的不仅仅是我正在压缩的提交。 这是我的工作流程: 各种功能分支通常会
晚上好。我目前正在为项目创建数据库。 场景如下: 新玩家可以在获得已注册并被工作人员接受。 根据年龄和性别将球员分成不同的组别(混合,女子公开赛,男子公开赛) 每场比赛有两名球员,其中 3 分记录套。
我正在尝试使用英语规则模拟 Squash 比赛的计分。它们是: 只有发球者赢得比赛才能获得积分。 如果发球者赢得一场比赛,他们将获得一分并继续担任发球者。 如果接力赛获胜,他们将成为发球者,但不会获得
我是一名优秀的程序员,十分优秀!