Git Rebase Hell

问题描述 投票:0回答:1

我有一个回购协议。有点混乱...

我可以让它保持原样,从现在开始继续使用适当的流程,但是......

我至少可以修复一些提交消息并保留旧分支作为历史记录吗?)

保留旧的提交日期也很好。

您不需要在分支之间移动提交或创建新分支,以使存储库看起来像是从一开始就以正确的流程完成的,但如果您愿意,我不会阻止您。

如何正确地将结果推送到gitlab?

这是生成示例存储库的脚本(在空目录中运行它):

enter image description here

#!/bin/bash
git init

# how to rebase it?
# need to fix some bad commit messages
# and prefer to keep old commit dates

# main
git branch -m main

# init commit #0
echo '#0 init commit in main' >> file.txt
git add file.txt
git commit --message="#0 init: all is fine for now"

# commit #1 (problem here)
sleep 1s 
echo 'commit #1 in main' >> file.txt
git add file.txt
git commit --message="#1 rebase and add a tag for this message"

# branching
# dev
git branch dev
git checkout dev
# feat
git branch feat
git checkout feat

# commit #2
sleep 1s 
echo 'commit #2 in feat' >> file.txt
git add file.txt
git commit --message="#2 feat: good commit"

# commit #3
sleep 1s 
echo 'commit #3 in feat' >> file.txt
git add file.txt
git commit --message="#3 feat: good commit"

# commit #4
sleep 1s 
git checkout main
echo 'commit #4 in main' >> file_2.txt
git add file_2.txt
git commit --message="#4 fix: small fix in main"

# merge #5
sleep 1s 
git checkout feat
git merge main --no-ff --message="#5 merge: main into feat"

# commit #6
sleep 1s 
echo 'commit #6 in feat' >> file.txt
git add file.txt
git commit --message="#6 feat: good commit"

# commit #7
sleep 1s 
echo 'commit #7 in feat' >> file.txt
git add file.txt
git commit --message="#7 rebase and add a tag for this message"

# commit #8
sleep 1s 
echo 'commit #8 in feat' >> file.txt
git add file.txt
git commit --message="#8 feat: good commit"

# commit #9
sleep 1s 
git checkout main
echo 'commit #9 in main' >> file_2.txt
git add file_2.txt
git commit --message="#9 style: small style fix in main"

# commit #10
sleep 1s 
git checkout feat
echo 'commit #10 in feat' >> file.txt
git add file.txt
git commit --message="#10 feat: good commit"

# merge #11
sleep 1s 
git checkout dev
git merge main --no-ff --message="#11 merge: main into dev"

# merge #12
sleep 1s 
git merge feat --no-ff --message="#12 merge: feat into dev"

# commit #13
sleep 1s 
echo 'commit #13 in dev' >> file_2.txt
git add file_2.txt
git commit --message="#13 refactor: good commit"

# commit #14
sleep 1s 
echo 'commit #14 in dev' >> file_2.txt
git add file_2.txt
git commit --message="#14 rebase and add a tag for this message"

# commit #15
sleep 1s 
echo 'commit #15 in dev' >> file_2.txt
git add file_2.txt
git commit --message="#15 refactor: good commit"

# merge #16
sleep 1s 
git checkout main
git merge dev --no-ff --message="#16 merge: dev into main and call it a release_##"

# branching
# hotfix
git branch hotfix
git checkout hotfix

# commit #17
sleep 1s 
echo 'commit #17 in hotfix' >> file_2.txt
git add file_2.txt
git commit --message="#17 fix: no more issues"

# merge #18
sleep 1s 
git checkout main
git merge hotfix --no-ff --message="#18 merge: hotfix into main"

# merge #19
sleep 1s 
git checkout dev
git merge hotfix --no-ff --message="#19 merge: hotfix into dev"

# end
git checkout main

我尝试变基:

git rebase --interactive --keep-base --rebase-merges  <SHA #0>

我希望它能够重建所有分支并仅更新消息...... 但它保留所有旧的提交,并在

main
分支之上添加所有内容的副本。看起来这个副本没有分支 - 它都在
main
内。

enter image description here

并且可以在变基后恢复提交日期:

git rebase --committer-date-is-author-date <SHA ##>

(一个接一个...约 40 次提交)

git github gitlab repository rebase
1个回答
0
投票

git rebase
不是在这里使用的正确工具。 Rebase 的目的是获取(单个引用的)提交列表并创建它们的副本,从而可能更改其父级。如果您只想更新提交消息,但保留历史记录的结构,则
git filter-branch
git filter-repo
更适合。

不清楚您想要如何准确地“修复消息”,但是

--msg-filter
filter-branch
在标准输入上接收原始消息,并且应该在标准输出上输出新消息。您可以将任何二进制文件、shell 脚本或函数传递给过滤器,包括
sed
awk
、python 文件或您编写的自定义程序。

git filter-branch --msg-filter '
msg="$(cat)" # get original message
if printf "%s\n" "$msg" | grep "#7"; then
  echo "#7 reworded message" # reword message
else
  printf "%s\n" "$msg" # keep message
fi
' -- --all

如果您有想要转移到新历史记录并需要更新的标签,请通过

--tag-name-filter cat


使用

filter-repo
,您可以使用
--message-callback '...'
选项,该选项接受将成为函数主体的 Python 代码 - 它必须返回新的/更新的消息,例如

git filter-repo --message-callback '
  if b"#7" in message:
    return "#7 reworded message" # reword message
  else:
    return message # keep message

使用您需要的任何复杂逻辑。


另一种方法是

git replace
,它使用 替换机制 来“隐藏”提交并显示替换引用中的替换提交。您可以使用
filter-branch
使替换提交永久化。

git replace --edit commit-7 # edit commit 7
git replace --edit ... # edit more commits
git replace --edit ...
git filter-branch -- --all # make replacements permanent
© www.soinside.com 2019 - 2024. All rights reserved.