对 git 存储库进行 rebase 的最简单方法是什么,以便只有当前分支的负责人保持完好,而其他所有内容都被压扁?最好是我可以应用于各种存储库的非交互式解决方案。
背景:我的存储库太大,因为它正在跟踪以前版本的大量遗留代码。我删除了我不再感兴趣的分支。对于剩余的分支,我想保留最终版本以用于存档目的,但清理所有中间更改。
因为我发现这个问题很有趣,所以我写了一个小 bash 脚本,它(类似于)你想要的。
您可以将其作为文件下载(或在 Github 上查看其 repo)并在下面找到源代码。这里有一点讨论:
用法:
./start_git_repo_fresh.sh [-r] [<path to git repo>]
where-r
允许创建公共根提交,路径让您可以从不同位置使用脚本;如果省略路径,则使用当前目录 (CWD)
该脚本的主要任务是移植当前存在的分支,只需使用它们的最新提交(因为 Git 提交是完整存储库的快照,这很容易)。
如果您指定该-r
标志,则会创建一个新的空根提交,并且所有分支都将创建为该根提交的直接后代。如果您不指定标志,则每个新分支都将有自己的根(它们将是孤立分支),并且每个分支都包含一个提交。
这是通过获取现有本地分支机构的一个分支并走过它们来完成的;对于每个分支(调用它BR
),脚本将:
-r
指定BR
-r
未指定_BR
BR
BR
使用来自的提交消息提交文件BR
BR
BR
如果在脚本启动时签出分支(repo 未处于分离的 HEAD状态),则该分支的新版本将在最后签出;如果 repo 位于分离的 HEAD 上,则最后创建的分支将被检出。
脚本来源:
#!/bin/bash
COMMON_ROOT=0
TEMP_ROOT_BRANCH="NEW_ROOT_COMMIT"
if [ "$1" == "-r" ]; then
COMMON_ROOT=1
shift 1
fi
if [ "$#" -eq 1 ]; then
cd "$1"
fi
branches=$(git branch --color=never)
orig_branch=$(echo "$branches" | grep --color=never "^\* " | sed "s/^\* //")
if [ "$COMMON_ROOT" -eq 1 ]; then
echo "Creating new (empty) common root commit"
git checkout --orphan "$TEMP_ROOT_BRANCH" 2> /dev/null
git rm -r --cached . >/dev/null
git clean -dfx > /dev/null
git commit --allow-empty -m "Initial commit" > /dev/null
fi
echo "$branches" | sed "s/^\* //" | while read branch; do
echo "Transplanting branch $branch"
newbranch="${branch}_new"
if [ "$COMMON_ROOT" -eq 1 ]; then
git checkout -b "$newbranch" "$TEMP_ROOT_BRANCH" > /dev/null 2>/dev/null
git checkout "$branch" -- . > /dev/null 2>/dev/null
else
git checkout "$branch" > /dev/null 2>/dev/null
git checkout --orphan "$newbranch" > /dev/null 2>/dev/null
fi
git commit -C "$branch" > /dev/null
git branch -D "$branch" > /dev/null
git branch -m "$newbranch" "$branch" > /dev/null
done
if [ "$COMMON_ROOT" -eq 1 ]; then
git branch -D "$TEMP_ROOT_BRANCH" > /dev/null
fi
if [ -n "$orig_branch" ]; then
git checkout "$orig_branch" 2>/dev/null
fi