Git重新设置本地分支的基础,该分支不';我没有遥控器

Git重新设置本地分支的基础,该分支不';我没有遥控器,git,git-rebase,Git,Git Rebase,我创建了一个本地分支(git checkout-b),在该分支中我进行了一些脏提交(“WIP”等等)。我从来没有推过遥控器。现在,我想在推送之前重命名/挤压一些提交: $ git rebase -i There is no tracking information for the current branch. Please specify which branch you want to rebase against. See git-rebase(1) for details gi

我创建了一个本地分支(
git checkout-b
),在该分支中我进行了一些脏提交(“WIP”等等)。我从来没有推过遥控器。现在,我想在推送之前重命名/挤压一些提交:

$ git rebase -i
There is no tracking information for the current branch.
Please specify which branch you want to rebase against.
See git-rebase(1) for details

    git rebase <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> feature/position-preview
问题是,我不想像现在这样推-u,因为这会导致糟糕的历史


如何重新设置新本地分支的基址?

问题是,默认情况下,无参数的重新基址建议从上次提交的分支重新基址。但是,我们可以将其推向正确的方向:

git rebase -i <hash>
git-rebase-i

在要在历史记录中看到的提交之前选择提交的
。这些散列可以通过git日志获得,git的文档是。。。有充分的理由:

git rebase[-i |--interactive][options][--exec][--to][[]

这里的参数标记为
upstream
,命令的有用(?)输出引用
git branch——将upstream设置为
origin/
,这意味着您的本地分支必须具有类似
origin/my feature的远程分支才能工作。但事实并非如此

git-rebase
所做的是复制一系列提交,每次复制就像在一个特定提交上运行
git-cherry-pick
。通过在提交图中复制某个线性提交链中的每个提交,您可以获得复制开发分支的效果。1我认为,用图的形式表示更合理。例如,假设您有以下序列:

... <- o <- A <- B    <-- master
         \
           C <- D <- E   <-- my-feature
这将创建一个新分支,
new my feature
,并复制三个提交,结果如下:

                C' - D' - E'   <-- new-my-feature
              /
... o - A - B   <-- master
      \
        C - D - E    <-- my-feature
旧的
my feature
上最初的三次提交“丢失”(它们通过“reflog”条目保留30天,但通常不可见,以免弄乱您的视图)

git rebase所做的是自动化这个过程:它找到一个要复制的提交序列,将序列复制到其他提交上,然后移动分支标签

您可以指定的是分支名称,默认名称是您当前的分支,通常是间接指定停止复制的点。rebase调用
--on
的“target”提交默认为您为rebase调用的
提供的参数(如果有)

其工作方式依赖于理解其他相当重要的东西,这会影响双点表示法

在我们进行任何樱桃采摘和树枝标签移动之前,让我们再次回到原始图形,即在重新基准之前:

... - o - A - B    <-- master
        \
          C - D - E   <-- my-feature
(这些都是我编的,但事实上,通过这种设置,你只会得到三个SHA-1)

我认为解释这一点的一个好方法是颜色填充/突出显示(当然,在本文中我不能这样做,所以你必须想象它)

假设您从
my feature
的提示开始,即提交
e
。把它漆成绿色:它是“待使用的”。然后,跟随其父指针返回commit
D
。把这个也漆成绿色。然后到
C
并将其涂成绿色;按此操作到
o
并将其中一个也涂成绿色,然后在整个图形中继续执行
o
的父级

然后,从
master
的提示开始,即提交
B
。把这个涂成红色:“停止”。然后,跟随它的父级提交
A
,并将这一个涂成红色。按此操作到
o
,然后在绿色油漆上涂上红色油漆:“停止”。始终跟随
o
的父母,用红色覆盖他们所有的绿色

(如果您愿意,可以先做红色,然后再做绿色,只要不将任何红色覆盖为绿色。)

结果是,
git rev list
应该列出的提交正是那些(仍然)绿色的提交,这正是我们想要重新设置基础的三个提交。即使我们从commit
B
启动了“红色列表”,这也是事实,
master
的提示

所有这些的简短版本是,为了重定基址,我们至少现在想要的是
git-rebase
master
视为“上游”。rebase的“上游”参数同时提供“红色油漆”参数、
master..my feature
修订说明符的左半部分,以及
--to
参数:我们希望复制提交,以便它们位于
master
的最尖端提交之后

事实上,您可以使用
git branch--set upstream to
master
(在您自己的私有存储库中)设置为
my feature
的“上游”。上游不必是像
原点/分支那样的远程跟踪分支
。你们当地的分支机构在这里会很好的运作。(但请记住,如果您确实开始共享此分支,将其推送到远程git存储库,如
origin
,那么您可能希望从那时起开始将远程跟踪分支用作“上游”,以提醒自己正在共享,并获得更典型的重基流。您可以更改“上游”在任何时候执行新的
git分支——将上游设置为


1“分支”一词是git文档问题的另一个例子。它至少有两种不同的含义。在作为脚注的段落的一部分的图表中,
master
是一个“分支”(我喜欢称之为“分支标签”或“分支名称”)。类似地,
myfeature
也是一个分支。在本例中,这两种方法只是分别标记一个特定的提交-
B
E
。但是,每个提交都有自己的指向其父提交的指针:
B
指向
A
E                C' - D' - E'   <-- new-my-feature
              /
... o - A - B   <-- master
      \
        C - D - E    <-- my-feature
                C' - D' - E'   <-- my-feature
              /
... o - A - B   <-- master
... - o - A - B    <-- master
        \
          C - D - E   <-- my-feature
$ git rev-list master..my-feature
e59f6c2d348d465e3147b11098126d3965686098
8413a79e67177d026d2d8e1ac66451b80bb25d62
1f9e0a53489aaca7859722e037a47e93858cbc42
$ git cherry-pick <id> <id> <id>
$ git cherry-pick my-feature~3..my-feature