如何将整个存储库压缩到第一次提交?

我可以将base转换为第一次提交,但这将留给我2次提交。 有没有办法在第一个提交之前引用这个提交?


当前回答

要做到这一点,你可以将本地git存储库重置为第一个commit标签,这样你在提交后的所有更改都将被取消,然后你可以使用——modify选项提交。

git reset your-first-commit-hashtag
git add .
git commit --amend

然后编辑第一个提交nam如果需要和保存文件。

其他回答

最简单的方法是使用'plumbing'命令update-ref删除当前分支。

你不能使用git branch -D,因为它有一个安全阀来阻止你删除当前的分支。

这会让你回到“初始提交”状态,在那里你可以开始一个新的初始提交。

git update-ref -d refs/heads/master
git commit -m "New initial commit"

要做到这一点,你可以将本地git存储库重置为第一个commit标签,这样你在提交后的所有更改都将被取消,然后你可以使用——modify选项提交。

git reset your-first-commit-hashtag
git add .
git commit --amend

然后编辑第一个提交nam如果需要和保存文件。

假设你的分支中有3个提交,并且它已经被推送到远程分支。

例子:

git log -4

将显示如下结果:

<your_third_commit_sha>
<your_second_commit_sha>
<your_first_commit_sha>
<master_branch_commit_sha - your branch created from master>

你想把最后3次提交压缩成一次提交,然后推送到远程分支。以下是步骤。

git reset --soft <master_branch_commit_sha>

现在所有提交的更改都被集成但未提交。验证:

git status

用一条消息提交所有更改:

git commit -m 'specify details'

强制将单次提交推到远程分支:

git push -f

一个衬套

你可以直接从HEAD创建一个squash-all commit,完全不需要rebase,只需要运行:

git reset $(git commit-tree HEAD^{tree} -m "A new start")

在~/.gitconfig中创建别名

[alias]
  squash-all = "!f(){ git reset $(git commit-tree HEAD^{tree} \"$@\");};f"

然后只要运行:git squash-all -m“一个全新的开始”

注意:要么从标准输入提供提交消息,要么通过-m/-F选项,就像git commit命令一样。参见git-commit-tree手册。

或者,您也可以使用以下命令创建别名:

git config --global alias.squash-all '!f(){ git reset $(git commit-tree HEAD^{tree} "$@");};f'

解释

create a single commit via git commit-tree What git commit-tree HEAD^{tree} -m "A new start" does is: Creates a new commit object based on the provided tree object and emits the new commit object id on stdout. The log message is read from the standard input, unless -m or -F options are given. The expression HEAD^{tree} represents the tree object corresponding to HEAD, namely the tip of your current branch. see Tree-Objects and Commit-Objects. reset the current branch to the new commit Then git reset simply reset the current branch to the newly created commit object. This way, nothing in the workspace is touched, nor there's need for rebase/squash, which makes it really fast. And the time needed is irrelevant to the repository size or history depth.


变体:项目模板中的新回购

这对于在新项目中使用另一个存储库作为模板/原型/种子/框架创建“初始提交”非常有用。例如:

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")

这避免了将模板回购作为远程(源或其他)添加,并将模板回购的历史记录折叠到初始提交中。

我通常是这样做的:

Make sure everything is committed, and write down the latest commit id in case something goes wrong, or create a separate branch as the backup Run git reset --soft `git rev-list --max-parents=0 --abbrev-commit HEAD` to reset your head to the first commit, but leave your index unchanged. All changes since the first commit will now appear ready to be committed. Run git commit --amend -m "initial commit" to amend your commit to the first commit and change the commit message, or if you want to keep the existing commit message, you can run git commit --amend --no-edit Run git push -f to force push your changes