您如何压缩整个存储库直到第一次提交?
我可以基于第一次提交,但这会使我留下2次提交。有没有办法在第一个提交之前引用提交?
--root
要压缩很多提交,实际上不是压缩所有提交的最佳解决方案):合并Git存储库的前两个提交?。
您如何压缩整个存储库直到第一次提交?
我可以基于第一次提交,但这会使我留下2次提交。有没有办法在第一个提交之前引用提交?
--root
要压缩很多提交,实际上不是压缩所有提交的最佳解决方案):合并Git存储库的前两个提交?。
Answers:
也许最简单的方法是使用工作副本的当前状态创建一个新的存储库。如果要保留所有提交消息,则可以先做git log > original.log
,然后在新存储库中为初始提交消息进行编辑:
rm -rf .git
git init
git add .
git commit
要么
git log > original.log
# edit original.log as desired
rm -rf .git
git init
git add .
git commit -F original.log
git rebase -i --root
。请参阅:stackoverflow.com/a/9254257/109618
从git 1.6.2开始,您可以使用git rebase --root -i
。
对于除第一个提交之外的每个提交,更改pick
为squash
。
squash
用于所有提交。第一个需要是pick
。
我做了一个别名git squash-all
。
用法示例:git squash-all "a brand new start"
。
[alias]
squash-all = "!f(){ git reset $(git commit-tree HEAD^{tree} -m \"${1:-A new start}\");};f"
警告:请记住要提供注释,否则将使用默认的提交消息“ A new start”。
或者,您可以使用以下命令创建别名:
git config --global alias.squash-all '!f(){ git reset $(git commit-tree HEAD^{tree} -m "${1:-A new start}");};f'
git reset $(git commit-tree HEAD^{tree} -m "A new start")
注意:这里“A new start
”只是一个示例,请随时使用您自己的语言。
无需压扁,使用 git commit-tree
可以创建一个孤儿提交并进行处理。
通过创建一个提交 git commit-tree
什么git commit-tree HEAD^{tree} -m "A new start"
是:
基于提供的树对象创建一个新的提交对象,并在stdout上发出新的提交对象ID。除非给出-m或-F选项,否则将从标准输入中读取日志消息。
该表达式HEAD^{tree}
表示与对应的树对象HEAD
,即当前分支的尖端。请参见Tree-Objects和Commit-Objects。
将当前分支重置为新提交
然后git reset
只需将当前分支重置为新创建的提交对象即可。
这样,工作空间中的任何东西都不会受到影响,也不需要重新设置基准/压扁,这使得它真的非常快。而且所需的时间与存储库大小或历史记录深度无关。
这对于在使用另一个存储库作为模板/原型/种子/骨架的新项目中创建“初始提交”很有用。例如:
cd my-new-project
git init
git fetch --depth=1 -n https://github.com/toolbear/panda.git
git reset --hard $(git commit-tree FETCH_HEAD^{tree} -m "initial commit")
这样可以避免将模板存储库添加为远程存储库(origin
或其他方式),并将模板存储库的历史记录折叠到您的初始提交中。
git push -f
用于传播。
git clone
。如果添加--hard
到git reset
并在中切换HEAD
,FETCH_HEAD
则git commit-tree
可以在获取模板存储库后创建初始提交。我已经在答案的最后部分演示了这一点。
${1?Please enter a message}
如果您只想将所有提交压缩为根提交,则
git rebase --interactive --root
可以正常工作,对于大量提交(例如,数百次提交)来说是不切实际的,因为重新生成基础操作可能会非常缓慢地运行,以生成交互式重新生成编辑器提交列表,以及运行重新生成自身。
当您压缩大量提交时,有两个更快,更有效的解决方案:
您可以简单地在当前分支的尖端(即最近的提交)创建一个新的孤立分支。这个孤立的分支构成了一个全新的独立提交历史记录树的初始根提交,这实际上等效于压缩所有提交:
git checkout --orphan new-master master
git commit -m "Enter commit message for your new initial commit"
# Overwrite the old master branch reference with the new one
git branch -M new-master master
说明文件:
另一个有效的解决方案是简单地对根提交使用混合或软复位<root>
:
git branch beforeReset
git reset --soft <root>
git commit --amend
# Verify that the new amended root is no different
# from the previous branch state
git diff beforeReset
说明文件:
git push origin master --force
。
git push --force
echo "message" | git commit-tree HEAD^{tree}
这将创建一个带有HEAD树的孤立提交,并在stdout上输出其名称(SHA-1)。然后在那儿重置您的分支。
git reset SHA-1
git reset $(git commit-tree HEAD^{tree} -m "commit message")
会更容易。
echo "message" | git commit-tree "HEAD^{tree}"
这是我最终要这样做的方式,以防万一它适用于其他人:
请记住,这样做总是有风险的,在开始之前创建保存分支从来都不是坏主意。
从记录开始
git log --oneline
滚动到第一次提交,复制SHA
git reset --soft <#sha#>
替换<#sha#>
从日志复制的SHA
git status
确保所有内容均为绿色,否则运行 git add -A
git commit --amend
将所有当前更改修改为当前第一次提交
现在强行推动此分支,它将覆盖那里的内容。
首先,使用将所有提交压缩为单个提交git rebase --interactive
。现在,您剩下两次壁球提交了。为此,请阅读
创建一个备份
git branch backup
重置为指定的提交
git reset --soft <#root>
然后将所有文件添加到暂存
git add .
提交而不更新消息
git commit --amend --no-edit
推送新的分支并压缩回购
git push -f
<root>
您重置回的提交。git commit --amend --no-edit
将所有更改提交到当前提交,而<root>
无需编辑提交消息。
假设除了创建一个提交(无父母无历史记录)之外,您还希望保留该提交的所有提交数据,那么上述答案在上面的几个方面有所改进(请对它们进行投票):
当然,新/单次提交的commit-SHA将发生变化,因为它表示新的(非)历史记录,成为无父母/根提交。
可以通过读取git log
和设置一些变量来完成git commit-tree
。假设您要master
在新分支中创建一个提交one-commit
,并保留上面的提交数据:
git checkout -b one-commit master ## create new branch to reset
git reset --hard \
$(eval "$(git log master -n1 --format='\
COMMIT_MESSAGE="%B" \
GIT_AUTHOR_NAME="%an" \
GIT_AUTHOR_EMAIL="%ae" \
GIT_AUTHOR_DATE="%ad" \
GIT_COMMITTER_NAME="%cn" \
GIT_COMMITTER_EMAIL="%ce" \
GIT_COMMITTER_DATE="%cd"')" 'git commit-tree master^{tree} <<COMMITMESSAGE
$COMMIT_MESSAGE
COMMITMESSAGE
')
对我来说,它的工作方式是这样的:我总共进行了4次提交,并使用了交互式rebase:
git rebase -i HEAD~3
第一次提交仍然存在,我进行了3次最新提交。
如果您卡在接下来出现的编辑器中,则会看到类似以下内容:
pick fda59df commit 1
pick x536897 commit 2
pick c01a668 commit 3
您必须先提交,然后再挤压其他人。您应该拥有的是:
pick fda59df commit 1
squash x536897 commit 2
squash c01a668 commit 3
为此,请使用INSERT键更改“插入”和“编辑”模式。
要保存并退出编辑器,请使用:wq
。如果您的光标在这些提交行之间或其他位置,请按ESC,然后重试。
结果,我有两次提交:剩下的第一次提交,第二次带有消息“这是3次提交的组合”。
在此处检查详细信息:https : //makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit
我通常这样做:
确保所有内容都已提交,并记下最新的提交ID,以防出现问题,或者创建单独的分支作为备份
运行git reset --soft `git rev-list --max-parents=0 --abbrev-commit HEAD`
以将头重置为第一次提交,但保持索引不变。自第一次提交以来的所有更改现在都可以随时提交了。
跑 git commit --amend -m "initial commit"
以将提交修改为第一个提交并更改提交消息,或者如果要保留现有的提交消息,则可以运行git commit --amend --no-edit
运行git push -f
到力推更改