21

在编写新代码时,我会进行许多小的提交来跟踪我的更改。但是,我的公司更喜欢将每个功能作为单个提交提交。所以解决方案是将我的整个(本地)分支压缩为一个提交。

如何在不使用git rebase --interactive然后更改picksquash所有提交的情况下压缩整个分支?

4

7 回答 7

18

我首选的方法是双线(不包括下面的步骤 1 和 4)。好处是您不需要知道/记录任何提交 ID,您可以编写一个简单的别名来执行所有涉及的步骤,并且您实际上将整个分支移动到origin /master 以便实际合并到 master 可以很快-forward,不能有任何冲突。

首先,我的假设:

  • 您正在一个名为my-feature-branch. 这个分支已经偏离master了几个提交;这是签出的分支。
  • 您的本地master跟踪远程分支origin/master
  • 您想将所有提交压缩到当前原始my-feature-branch状态/主状态之上的单个提交(不是您的本地,可能已过时)master
  • 您的所有更改都已提交,您没有未暂存的更改(它们将在 期间丢失git reset --hard

我的流程如下:

  1. 获取,origin/master当前也是:

    $ git fetch
    
  2. 通过将其重置为指向来丢弃本地分支上的所有提交origin/master

    $ git reset --mixed origin/master
    
  3. 将分支先前状态的所有旧更改合并到索引中

    $ git merge --squash HEAD@{1}
    
  4. 提交您的更改 - Git 将使用包含来自压缩提交的所有提交消息的提交消息预先填充您的编辑器

我提到的简单别名是:

alias squash="git fetch; git reset --mixed origin/master; git merge --squash HEAD@{1}"
于 2014-12-29T23:26:18.547 回答
13

这是一个完美的用例git reset --soft

假设你有提交历史

D   Your latest patch
C   Your second patch
B   Your first patch
A   Someone else's work

没有阶段性更改,并且git statusgit loggit show告诉您当前处于提交 D。

然后git reset --soft B将获取提交的累积更改C并将D它们暂存以进行提交。git commit --amend然后会将这些更改“合并”到提交 B 中。

使用如下:

git reset --soft B
git commit --amend

第二个命令将使您的编辑器有机会编辑提交消息。

请注意,如果您在开始此过程之前已暂存更改(您已完成git add XXX但未跟进 a git commit),那么这些暂存更改也将合并到提交中。

于 2019-09-25T14:38:36.483 回答
9

可能最好的选择是git merge --squash在合并时使用。这将使您的分支随着它的开发而离开,这通常更容易进行故障排除,因为您会有一些“我正在更改提交 Z 中的特定功能”的概念,并且查看该特定提交,您拥有所有您对多个文件所做的任何更改的上下文 - 查看作为开发路径压缩结果的单个提交会使您更难记住“哦,是的,我不得不在不同的文件中更改另一件事, 也...”。git bisect当你有整个路径可用时,你也可以使用它——在被压扁的情况下,它所能告诉你的只是“这个巨大的提交破坏了一些东西”。

使用的结果git merge --squash是您“合并”到的分支上的单个提交,其中包含来自您的分支的累积更改,但它只留下您的原始分支。

于 2014-12-29T23:29:09.937 回答
6

在您开始分支之前找到提交的哈希并将其复制到剪贴板中。然后重置到该哈希。

$ git reset [hash]

然后只需在一条消息中重新添加并重新提交更改。

$ git add -A
$ git commit -m 'EVERYTHING SQUASHED'
于 2014-12-29T23:08:37.597 回答
2

编辑您的 git 配置文件~/.gitconfig并将以下内容添加到别名部分

[alias]
    squash = "!f(){ CUR=`git rev-parse HEAD` && git reset --soft ${1} && git commit -m \"$(git log --format=%B ${1}..${CUR})\"; };f"

此别名获取当前 HEAD 提交哈希,重置回您指定的提交,并创建一个新提交,保留所有提交消息。

用法:

git squash <refspec>

refspec 可以是任何有效的提交引用,例如提交哈希、分支名称、标签名称、HEAD^ HEAD~3

于 2014-12-29T17:24:33.850 回答
0

最好的办法是进行硬重置并将以前的 HEAD 与壁球合并。这是一个别名:

[alias]
  squash = "!f() { git reset --hard $1; git merge --squash HEAD@{1}; git commit; }; f"

这样你就可以这样称呼它:

git squash master

或者从另一个分支挤压,比如dev

git squash dev
于 2019-01-15T18:16:47.893 回答
0

我认为这不是这个问题的正确答案。

但我通常在使用以下命令向远程上游主服务器发出拉取请求之前压缩我的分支:

git rebase -i master

但是你仍然必须选择要挑选和挤压的东西。

于 2015-11-08T08:40:47.657 回答