ChatGPT解决这个技术问题 Extra ChatGPT

推送后如何在git中压缩提交?

这很好地解释了压缩多个提交:

http://git-scm.com/book/en/Git-Branching-Rebasing

但它不适用于已经推送的提交。如何压缩本地和远程存储库中最近的几次提交?

当我执行 git rebase -i origin/master~4 master 时,将第一个保留为 pick,将其他三个设置为 squash,然后退出(通过 emacs 中的 cx cc),我得到:

$ git rebase -i origin/master~4 master
# Not currently on any branch.
nothing to commit (working directory clean)

Could not apply 2f40e2c... Revert "issue 4427: bpf device permission change option added"
$ git rebase -i origin/master~4 master
Interactive rebase already started

其中 2f40 是 pick 提交。现在 4 个提交中没有一个出现在 git log 中。我希望我的编辑器会重新启动,以便我可以输入提交消息。我究竟做错了什么?

不是那么全面,但易于阅读:internalpointers.com/post/squash-commits-into-one-git

h
hrvoj3e

壁球在本地提交

git rebase -i origin/master~4 master

然后用力推

git push origin +master

--force 和 + 之间的区别

git push 的文档中:

请注意, --force 适用于所有被推送的引用,因此将它与 push.default 设置为匹配或配置为 remote.*.push 的多个推送目标一起使用可能会覆盖当前分支以外的引用(包括本地引用严格落后于他们的远程对手)。要强制只推送到一个分支,请在 refspec 前使用 + 来推送(例如 git push origin +master 强制推送到主分支)。


您还可以git push --force origin master
Daenyth:是的,但我总是更喜欢这种语法,因为它更短。
当然,要意识到如果其他人可能已经从远程存储库中提取了,你可能不想这样做——在这种情况下,答案是“你不想”。
另外,我认为 OP 正在完全复制命令 git rebase -i origin/master,并且实际上想知道如何将提交变基比这更远,例如 git rebase -i origin/master~20 master
gstackoverflow+ 仅强制以它为前缀的 refspec。 --force 将强制推送所有 refspec。请参阅更新的答案。
j
jakob-r

在一个分支上,我能够这样做(对于最后 4 次提交)

git checkout my_branch
git reset --soft HEAD~4
git commit
git push --force origin my_branch

在已经推送的分支上使用软命令执行此操作最终会为我推送大量其他人的提交。
一吨?怎么可能超过4?你能详细说明吗?
我不确定,但这与试图压缩已经推送的提交有关。看起来其他人在这里遇到过类似的情况 - stackoverflow.com/questions/5189560/…
我会接受这个作为预期的答案。接受答案的更清洁。
这是只需 4 个步骤即可获得的最明确和公认的答案
K
KetZoomer

与接受的答案略有不同,但我在挤压时遇到了很多困难,最终得到了它。

$ git rebase -i HEAD~4

在打开的交互式屏幕上,将顶部的 pick 替换为 squash 以获取您想要压缩的所有提交。

保存并关闭编辑器

使用以下命令推送到远程:

$ git push origin branch-name --force

简短有效,详细:
esc --> :wq 前提是编辑器是 vi 或 vim
正确和准确。力推很重要。推前不要拉。
感谢那!只是给其他人的注释,我使用 +branch-name 而不是 branch-name --force,正如另一个答案中所建议的那样 - 应该更安全 (stackoverflow.com/a/5668050/997940)
S
Stuart Cardall

只需创建一个 branch 来处理 & 就可以避免很多问题。 master 上工作:

git checkout -b mybranch

以下适用于已推送的 remote 次提交 & remote 推送提交/local 仅提交的混合:

# example merging 4 commits

git checkout mybranch
git rebase -i mybranch~4 mybranch

# at the interactive screen
# choose fixup for commit: 2 / 3 / 4

git push -u origin +mybranch

我也有一些可能会有所帮助的pull request notes


N
Nupur

git rebase -i master

您将打开编辑器 vm 并发送类似这样的消息

Pick 2994283490 commit msg1
f 7994283490 commit msg2
f 4654283490 commit msg3
f 5694283490 commit msg4
#Some message 
#
#some more

在这里,我将所有其他提交的选择更改为“f”(代表修复)。

git push -f origin feature/feature-branch-name-xyz

这会将所有提交修复为一个提交,并将删除所有其他提交。我这样做了,它帮助了我。


这需要成为最佳答案,谢谢。我发现这个答案是一种更好的压缩方法,而不是根据提交次数盲目地进行压缩。尤其是使用 VM 编辑器,您可以一次做很多事情,比如更改提交、删除提交,当然还有压缩。
G
Gavin

1) git rebase -i HEAD~4

详细说明:它适用于当前分支; HEAD~4 表示压缩最近的四个提交;交互模式 (-i)

2)此时,编辑器打开了提交列表,以更改第二个和后续提交,将 pick 替换为 squash 然后保存。

输出:成功地重新定位和更新了 refs/heads/branch-name。

3) git push origin refs/heads/branch-name --force

输出:

remote:
remote: To create a merge request for branch-name, visit:
remote: http://xxx/sc/server/merge_requests/new?merge_request%5Bsource_branch%5D=sss
remote:To ip:sc/server.git
 + 84b4b60...5045693 branch-name -> branch-name (forced update)

v
vonaka

为了在单个分支上压缩两个提交,其中一个已经被推送,以下工作:

git rebase -i HEAD~2
    [ pick     older-commit  ]
    [ squash   newest-commit ]
git push --force

默认情况下,这将包括最新提交的提交消息作为对旧提交的评论。


A
Alex

当您使用 Gitlab 或 Github 时,您可能会以这种方式遇到麻烦。您使用上述方法之一压缩您的提交。我最喜欢的是:

git rebase -i HEAD~4
or
git rebase -i origin/master

为您的提交选择 squash 或 fixup。此时,您将使用 git status 进行检查。消息可能是:

    On branch ABC-1916-remote
    Your branch and 'origin/ABC-1916' have diverged,
    and have 1 and 7 different commits each, respectively.
      (use "git pull" to merge the remote branch into yours)

你可能会想拉它。不要那样做,否则您将处于与以前相同的情况。

而是通过以下方式推送到您的原点:

git push origin +ABC-1916-remote:ABC-1916

+ 允许强制推送到一个分支。


拉动没有任何问题,特别是如果您有冲突,它们可以比强行推动更容易解决
@Ray_Poly - 这不会将那些远程提交作为本地提交放回原处吗?这就是我发现的。
是的,它会创建一个新的提交,但是您可以在该提交中看到差异,这比每次 rebase 时都重写 git 历史记录要好
c
cb4

Sqush 远程更改

首先确保您的本地主机与远程主机相同

然后将您的本地功能分支重置为与 master 相同: git reset --soft master

然后将所有修改和更改(您在刚刚重置为 master 的本地功能分支上所做的)添加到暂存区域: git add 。

然后提交这些更改: git commit -m "this is the final commit message"

然后强制推送到远程分支: git push RemoteBranch --force


S
Sasi Kumar M

在我的情况下,要求是将所有功能分支提交压缩为一个,以拥有干净的提交历史记录。利用 GitHub UI 来做到这一点。

问题:

功能分支(例如:featureBranch)已从 master(一个月前)创建。

提交我对 featureBranch 的所有更改(约 12 次提交,一个月的工作)。并定期被推送到远程。

要求:

使用 master 更新功能分支并在 featureBranch 中进行一次提交

后续步骤:

在 GitHub UI 中从 master 创建一个新分支(例如:featureBranchLatest)。

创建一个从 featureBranch 到 featureBranchLatest 的 PR。

如果有冲突,请解决。将 PR 与 GitHub UI 中的 squash 提交选项合并。 (更改提交消息以获得更清晰的消息)。

现在 featureBranchLatest 将在一次提交中包含所有需要的更改,以及来自 master 的最新更改。如果不需要参考,请删除旧分支 featureBranch。