# 合并多个commit

文件少的话可以先: `git reset --soft` 然后重新 `git commit` , 这样又简单又好理解。

&#x20;`rebase -i` 合并比较麻烦，利用 rebase 做分支之间的变基会比较好；

下面还是介绍一下rebase的用法：

### 查看版本历史

```
git log

* b1b8189 - (HEAD -> master) Commit-3
* 5756e15 - Commit-2
* e7ba81d - Commit-1
* 5d39ff2 - Commit-0
```

### 执行git rebase变基

`-i` 实际上就是 `--interactive` 的简写，在使用 `git rebase -i` 时，我们要在后面再添加一个参数，这个参数应该是 **最新的一个想保留的 Commit**。这句话读起来有点坳口，所以这个情况下通常需要举个例子。就我们前面提到的那个例子中，这个「最新的一个想保留的 Commit」就是 `5d39ff2(Commit-0)`，于是我们的命令看起来就长这样：

```
git rebase -i 5d39ff2
```

请注意5d39ff2这个版本是不参与合并的，可以把它当做一个坐标

### 选择要合并的commit

上一步操作按下回车键后会出现

```
pick e7ba81d Commit-1
pick 5756e15 Commit-2
pick b1b8189 Commit-3
```

前面三行是我们需要操作的三个 Commit，每行最前面的是对该 Commit 操作的 Command。关于每个 Command 具体做什么，下面的注释写得非常清楚。为了完成我们的需求，我们可以关注到这两个命令：

* `squash`：使用该 Commit，但会被合并到前一个 Commit 当中
* `fixup`：就像 `squash` 那样，但会抛弃这个 Commit 的 Commit message

由于我们是想把三个 Commit 都合并在一起，并且使 Commit Message 写成 Commit-1，所以我们需要把 5756e15(Commit-2) 和 b1b8189(Commit-3) 前面的 pick 都改为squash，于是它看起来像这样：

```
pick e7ba81d Commit-1
squash 5756e15 Commit-2
squash b1b8189 Commit-3
```

也可以用缩写

```
pick e7ba81d Commit-1
s 5756e15 Commit-2
s b1b8189 Commit-3
```

### 保存继续

上一步操作完保存退出后，Git会压缩提交历史，如果有冲突，需要修改，修改的时候要注意，保留最新的历史，不然我们的修改就丢弃了。修改以后要记得敲下面的命令：

```
git add .  
git rebase --continue  
```

如果要放弃的话，则使用

```
git rebase --abort
```

### push

推荐使用

```
git push --force-with-lease
```

{% hint style="info" %}
**git push --force 命令有什么安全问题？**

`--force` 会使用本地分支的提交覆盖远端推送分支的提交。也就是说，如果其他人在相同的分支推送了新的提交，你的这一举动将“删除”他的那些提交！就算在强制推送之前先 `fetch` 并且 `merge` 或 `rebase` 了也是不安全的，因为这些操作到推送之间依然存在时间差，别人的提交可能发生在这个时间差之内。
{% endhint %}

{% hint style="info" %}
**请特别注意**——如果你 `fetch` 之后在本地的 origin 相关分支上已经看到了别人的提交，依然进行强制推送，你还是会覆盖别人的提交。也就是说，`--force-with-lease` **解决的是本地仓库不够新时，依然覆盖了远端新仓库的问题**，如果你**执意想要覆盖远端提交**，只需要先 `fetch` 再推送，**它也不会拒绝的**。
{% endhint %}

{% hint style="info" %}
GitHub 的工作流或者 GitLab 的工作流中，都有一种行为是 `rebase` 自己的分支到 `origin/master` 上，以保证 `master` 分支上的提交是纯粹的干净的。也就是说，本意是禁止对合并到 `master` 或 `develop` 分支上的提交进行 `rebase`；但对于自己的 `temp` 分支或者 `feature` 分支，因为提交还没有合并到主干中，随时删除掉或者将历史进行美化也不会造成太大的问题。
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mm.ricky.moe/other/git/he-bing-duo-ge-commit.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
