无需先创建replace引用,如何直接复制Git提交并修改父提交?
更直接的Git提交复制与父提交替换方法
当然有更直接的方案,无需借助git replace的临时引用,直接通过git commit-tree结合原提交的信息提取就能一步生成符合要求的新提交。
方法一:分步提取原提交属性
先从目标提交中提取所有需要复用的属性,再用git commit-tree创建新提交:
# 读取原提交的完整信息 commit_info=$(git cat-file commit <sha>) # 提取树哈希、作者、提交者信息和提交消息 tree=$(echo "$commit_info" | grep '^tree ' | cut -d' ' -f2) author=$(echo "$commit_info" | grep '^author ' | cut -d' ' -f2-) committer=$(echo "$commit_info" | grep '^committer ' | cut -d' ' -f2-) message=$(echo "$commit_info" | sed '1,/^$/d') # 生成新提交,指定新父提交 new_commit_sha=$(echo "$message" | git commit-tree $tree -p <new_parent_sha> --author="$author" --committer="$committer")
这个方法的核心是:
- 直接复用原提交的树哈希,确保新提交的文件内容和原提交完全一致
- 通过
--author和--committer参数完整继承原提交的作者、提交者及对应的日期信息 - 提交消息原样传递,保证和原提交完全相同
-p <new_parent_sha>用来指定新的父提交,这是唯一的改动点
方法二:简洁的单命令写法
如果觉得分步提取太繁琐,可以用git show的格式化输出直接获取所需信息,整合成单条命令:
new_commit_sha=$(git show --pretty=format:"%B" <sha> | git commit-tree $(git rev-parse <sha>:tree) -p <new_parent_sha> --author="$(git show --pretty=format:"%an <%ae> %ad" <sha>)" --committer="$(git show --pretty=format:"%cn <%ce> %cd" <sha>)")
各部分的作用:
git rev-parse <sha>:tree:快速获取原提交的树哈希git show --pretty=format:"%an <%ae> %ad" <sha>:提取包含姓名、邮箱、日期的完整作者信息git show --pretty=format:"%cn <%ce> %cd" <sha>:提取包含姓名、邮箱、日期的完整提交者信息git show --pretty=format:"%B" <sha>:提取包含换行的完整提交消息
这两种方式都能避免git cherry-pick可能带来的冲突问题,因为完全没有补丁应用的过程,只是基于原提交的树和属性创建新提交,唯一的变化就是父提交。
内容的提问来源于stack exchange,提问作者merlin2011
相关产品推荐
相关产品推荐

