在推入Git之前组合多个提交

在推入Git之前组合多个提交,git,git-squash,Git,Git Squash,我在本地存储库中有一堆主题相似的提交。我想在推到远程服务器之前将它们组合成一个提交。我该怎么做?我认为,rebase可以做到这一点,但我无法理解这些文档。您可能想要使用这些文档,在该链接中有详细描述 如果您搜索“git rebase interactive”,您可以找到其他好的资源。您可以使用git rebase-i,传入您想要用作“根”的修订版: git rebase -i origin/master 将打开一个编辑器窗口,显示上次在origin/master中提交后所做的所有提交。您可以拒

我在本地存储库中有一堆主题相似的提交。我想在推到远程服务器之前将它们组合成一个提交。我该怎么做?我认为,
rebase
可以做到这一点,但我无法理解这些文档。

您可能想要使用这些文档,在该链接中有详细描述


如果您搜索“git rebase interactive”,您可以找到其他好的资源。

您可以使用
git rebase-i
,传入您想要用作“根”的修订版:

git rebase -i origin/master
将打开一个编辑器窗口,显示上次在
origin/master
中提交后所做的所有提交。您可以拒绝提交、将提交压缩为单个提交或编辑以前的提交

有一些参考资料可以更好地解释这一点,并展示一些其他示例:


是我能找到的前两个好页面。

在git中,你想做的就是“挤压”。执行此操作时有很多选项(太多?),但如果您只想将所有未推送的提交合并到一个提交中,请执行以下操作:

git rebase -i origin/master
这将打开您的文本编辑器(
-i
用于“交互式”),其中的文件如下所示:

pick 16b5fcc Code in, tests not passing
pick c964dea Getting closer
pick 06cf8ee Something changed
pick 396b4a3 Tests pass
pick 9be7fdb Better comments
pick 7dba9cb All done
将所有
pick
更改为
squash
(或
s
),第一个除外:

pick 16b5fcc Code in, tests not passing
squash c964dea Getting closer
squash 06cf8ee Something changed
squash 396b4a3 Tests pass
squash 9be7fdb Better comments
squash 7dba9cb All done
保存文件并退出编辑器。然后,将打开另一个文本编辑器,让您将所有提交中的提交消息合并到一个大的提交消息中


瞧!谷歌搜索“git squashing”将为您提供所有其他可用选项的解释。

如果您有大量提交,并且您只想压缩最后的X个提交,请找到要开始压缩的提交的提交ID并执行此操作

git rebase -i <that_commit_id>
您可以这样做(写入提交次数):

或者这样(写下你不想挤压的上一次提交的哈希值):

我想出了

#!/bin/sh

message=`git log --format=%B origin..HEAD | sort | uniq | grep -v '^$'`
git reset --soft origin
git commit -m "$message"
合并、排序、统一并删除提交消息中的空行。我使用它对github wiki进行本地更改(使用gollum)

您可以使用交互式重基挤压(加入)提交。有一个非常好的YouTube视频显示了如何在命令行上或使用:

如果您已经是SmartGit用户,则可以选择所有传出提交(通过按住Ctrl键)并打开上下文菜单(右键单击)以压缩提交

非常舒服:

还有一个非常好的教程,其中展示了它的工作原理:


而我挤压多个
push
的方法是(也许您将许多提交推送到了自己的分支,现在您希望执行一个pull请求,并且不希望将它们与您已经推送的许多提交混在一起)。我这样做的方式(据我所知,没有其他更简单的选择)

  • 创建新的分支以便
    挤压
    (从您希望将请求拉入的原始分支中进行分支)
  • 推送新创建的分支
  • 将提交(已推送)到新分支的分支合并
  • 重新固定新的树枝和南瓜
  • 推动新的分支
  • 为新分支创建新的拉请求,该分支现在只有一个提交
  • 例如:

    git checkout from_branch_you_wish_to_pull_request_to
    git checkout -b new_branch_will_have_single_squashed_commit
    git push -u new_branch_will_have_single_squashed_commit
    git merge older_branch_with_all_those_multiple_commits
    git rebase -i (here you squash)
    git push origin new_branch_will_have_single_squashed_commit
    

    现在,您可以将请求从您希望的分支拉入
    ,将请求拉入
    ,这里有很多可行的答案,但我发现这是最简单的。此命令将打开一个编辑器,您可以在其中用
    squash
    替换
    pick
    ,以便将它们删除/合并为一个编辑器

    git rebase -i HEAD~4
    

    其中,
    4
    是要压缩为一个的提交数。这也解释了。

    通过
    origin/master
    ,您的意思是
    ?如果配置了上游分支,它是隐式的还是必须指定它?使用
    fixup
    而不是
    squash
    跳过创建新提交消息的步骤。最后一条提交消息(“全部完成”)将自动用于
    rebase
    @Jusleong创建的最终提交。您只需删除该行即可删除提交中的更改。有人知道您的“pick”行中是否有多行提交消息,或者它会混淆解析器吗?很好!您也可以使用s而不是squash来对任意数量的提交进行重定基址/压缩,请参见.Related.“我看不懂文档”通常您在这样做之前应该三思而后行。更细粒度(更小)的提交有许多实际好处。如果需要对它们进行分组,可以将它们全部放在一个单独的分支中,并使用git merge--no ff myOtherBranch
    将该分支合并到主分支中。或者,您可以在提交消息中使用提交消息前缀或标记。git历史不是公共变更日志,而是开发人员使用的“内部”结构。这确实是一个非常聪明的想法!出于某种原因(可能是我的配置或我使用GIT的方式),origin..HEAD给了我一个模棱两可的参数错误。为了确保它总是获取与当前分支头的差异,我需要将带有
    git日志的第一行改编为
    git fetch&&git log--format=%B fetch_head..head
    […]首先抓取确保GIT拥有所需的最新知识,并创建了一个我们可以使用的FETCH_HEAD ref。我花了一些时间才弄清楚,但它本身似乎不会被挤压。它应该说“在要挤压成一组提交之前找到提交的提交ID”。这有什么特别之处吗?我有一个PR,它有5次提交(包括一次合并合并冲突修复),如果我在PR日志中指定第一次提交的提交ID,我只会在rebase pick/squash列表中得到一些随机的不相关的提交。除了mege+rebase,你还可以执行mege--squas
    #!/bin/sh
    
    message=`git log --format=%B origin..HEAD | sort | uniq | grep -v '^$'`
    git reset --soft origin
    git commit -m "$message"
    
    git checkout from_branch_you_wish_to_pull_request_to
    git checkout -b new_branch_will_have_single_squashed_commit
    git push -u new_branch_will_have_single_squashed_commit
    git merge older_branch_with_all_those_multiple_commits
    git rebase -i (here you squash)
    git push origin new_branch_will_have_single_squashed_commit
    
    git rebase -i HEAD~4