变基而不是快进

Rebase instead of fast forward

我是 GIT 的新手,我不知道我的问题是否已经有了答案。请在将其标记为重复之前仔细阅读。

我有一个分支,我们称它为 public,它被推送并与 origin 同步。有一次,我创建了另一个分支 private,它从 public 中弹出,因为我想做很多我想保密的工作。所以我只在 private 上工作,比方说,我做了 10 次提交,直到我最终达到可以 public.

的状态

现在,我显然 不想对 public 进行快进合并,因为所有中间提交都会出现在远程服务器上。 鉴于 public 分支没有偏离创建 private 的点,我该如何做 rebase 呢?

显然,我想在 public 分支上创建一个新提交,其中包含来自 10 private 次提交的所有修改。我知道翻译成 rebase,但我不知道该怎么做。

对您的 10 次提交使用 git rebase -i 和 select squash,因此您只会有一个基于 public 分支的大提交。

将 -i 与变基一起使用时,您将获得一个文本编辑器,您可以在其中选择每个提交的变基方式(或者是否完全变基)。 Squash 是允许您使用这种语法将多个提交集成到单个提交中的选项(来自 github 文档,下面的 link):

pick 1fc6c95 Patch A
pick 6b2481b Patch B
squash dd1475d something I want to split
squash c619268 A fix for Patch B
squash fa39187 something to add to patch A
squash 4ca2acc i cant' typ goods
squash 7b36971 something to move before patch B

这将变基 2 次提交:"Patch A" 将逐字记录 "Patch B" 将包括下一次 "squashed" 次提交的更改。

详情请见reference or the nice github doc page中的"Interactive Rebasing"。

首先,publictracking一个位于origin上的远程分支并不意味着本地分支public相当于远程分支origin/public

由于 git 的分布式特性,只要不推送,您可以在本地 public 分支上进行大量提交,而无需将任何内容发送到服务器。

关于您在当前系统状态下尝试做的事情,这里有一些详细的步骤,假设您不关心保留原来的 10 次提交。

  1. 开始针对远程服务器的当前状态进行交互式变基。

    git checkout private
    git rebase -i origin/public
    
  2. 将弹出一个编辑器。具体的编辑器将取决于平台和环境变量设置。在此编辑器中,您将看到 10 次提交的哈希值,在左侧栏中带有单词 "pick"。对于第一行,保留 pick。对于后续行,将 pick 替换为 squash。保存文件并退出编辑器。

  3. 此时,git 已经将 10 个提交合并为一个提交,因此我们可以合并到 public 并推送。

    git checkout public
    git merge private
    git push
    

如果您想在本地 private 分支上保留原来的 10 次提交,您可以改为在本地 public 分支上进行快进合并,然后在那里变基。

git checkout public
git merge private
git rebase -i origin/public
# Do the same rebase steps as above
git push

确切地说,在 public 上创建一个包含来自 private 的修改的新提交并不需要 rebase。它需要 merge.

Rebase 将 private 之前的提交压缩在一起似乎是你想要的,你保留一个分支和一个合并提交。

然而,由于您不关心 private 分支的详细历史记录,您也可以:

$ git checkout public
$ git merge --squash private
$ git commit

索引首先更新为 private 的内容,您可以在 public.

之上对其进行一次提交