Git rebase 检查父提交
Git rebase checks out parent commit
Git 在特定情况下表现异常,我能够重现该问题。我有两个分支,比如 master 和 feature,指向同一个提交。当我将 master 重置为父提交并尝试在 master 之上重新设置功能时,功能分支也指向父提交,尽管我希望 rebase 什么都不做。我不确定为什么会这样。
重现步骤:
运行 以下命令重现初始状态:
deepakgupta @ git init
Initialized empty Git repository in /tmp/hello/.git/
deepakgupta (master)@ touch hello
deepakgupta (master)@ git add hello
deepakgupta (master)@ git commit -m "First commit"
[master (root-commit) 1750f9c] First commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 hello
deepakgupta (master)@ touch world
deepakgupta (master)@ git add world
deepakgupta (master)@ git commit -m "Second commit"
[master 7411ad0] Second commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 world
deepakgupta (master)@ git branch feature
此时,git log
看起来是这样的:
commit 7411ad0984841b28dca630d54c3b079ebd01c7e9 (HEAD -> master, feature)
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date: Tue Apr 7 13:58:09 2020 +0530
Second commit
commit 1750f9c5ba95f53742005657e9cee41390165dc7
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date: Tue Apr 7 13:57:54 2020 +0530
First commit
现在试试:
git reset --hard HEAD^
git checkout feature
git branch --set-upstream-to master
现在是 git 日志现在看起来:
commit 7411ad0984841b28dca630d54c3b079ebd01c7e9 (HEAD -> feature)
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date: Tue Apr 7 13:58:09 2020 +0530
Second commit
commit 1750f9c5ba95f53742005657e9cee41390165dc7 (master)
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date: Tue Apr 7 13:57:54 2020 +0530
First commit
当我尝试 git rebase
时会发生什么?我觉得状态应该保持不变。
但它变为:
commit 1750f9c5ba95f53742005657e9cee41390165dc7 (HEAD -> feature, master)
Author: Deepak Gupta <deepak.gupta@rubrik.com>
Date: Tue Apr 7 13:57:54 2020 +0530
First commit
(END)
有人可以解释这种行为吗?
这个问题——或者说 特征,因为 Git 人喜欢提到它——是由于 Git 的 叉点模式。 The git rebase
documentation 描述如下:
If upstream
is not specified, the upstream configured in branch.<em>name</em>.remote
and branch.<em>name</em>.merge
options will be used (see git-config[1] for details) and the --fork-point
option is assumed. If you are currently not on any branch or if the current branch does not have a configured upstream, the rebase will abort.
(格式,尤其是粗体部分,是我的)。下一段提供了这个神秘的摘要:
All changes made by commits in the current branch but that are not in upstream
are saved to a temporary area. This is the same set of commits that would be shown by git log <upstream>..HEAD
; or by git log 'fork_point'..HEAD
, if --fork-point
is active (see the description on --fork-point
below); or by git log HEAD
, if the --root
option is specified.
(此描述省略了一些重要的项目:特别是,默认情况下也丢弃了等效于补丁 ID 的合并和提交。但这些都不会影响您的特定情况。)
分叉点描述在页面的中途。它提到:
fork_point
is the result of git merge-base --fork-point <upstream> <branch>
command (see git-merge-base[1]). If fork_point
ends up being empty, the upstream
will be used as a fallback.
upstream
是master
,branch
是当前分支,feature
。在我的存储库中,我现在 运行:
$ git merge-base --fork-point master feature
af07c3c48ff0d499400ac539aa9c665a8dddcd6f
(使用我在复制您的示例时创建的存储库中的哈希 ID)。让我们在我的存储库上使用 git log
来查看两个提交:
$ git log --decorate --oneline
af07c3c (HEAD -> feature) Second commit
dbf1741 (master) First commit
因此,鉴于 git merge-base --fork-point
的输出,rebase
承诺它将复制的提交是 git log af07c3c48ff0d499400ac539aa9c665a8dddcd6f..HEAD
:
显示的提交
$ git log af07c3c48ff0d499400ac539aa9c665a8dddcd6f..HEAD
$
未列出任何提交,因此未复制任何提交。
如何解决问题
要禁用分叉点模式,运行:
git rebase --no-fork-point
或:
git rebase master
即使当前分支 feature
的上游是 master
,一个 explicit git rebase master
disables 默认叉点模式。在使用明确的分支名称时强制 Git 使用分叉点模式——如果你想这样做的话;在这种情况下,您可能不想要它——您也可以运行:
git rebase --fork-point master
完全没有任何参数,你会得到 git rebase --fork-point master
的效果。
Git 在特定情况下表现异常,我能够重现该问题。我有两个分支,比如 master 和 feature,指向同一个提交。当我将 master 重置为父提交并尝试在 master 之上重新设置功能时,功能分支也指向父提交,尽管我希望 rebase 什么都不做。我不确定为什么会这样。
重现步骤:
运行 以下命令重现初始状态:
deepakgupta @ git init
Initialized empty Git repository in /tmp/hello/.git/
deepakgupta (master)@ touch hello
deepakgupta (master)@ git add hello
deepakgupta (master)@ git commit -m "First commit"
[master (root-commit) 1750f9c] First commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 hello
deepakgupta (master)@ touch world
deepakgupta (master)@ git add world
deepakgupta (master)@ git commit -m "Second commit"
[master 7411ad0] Second commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 world
deepakgupta (master)@ git branch feature
此时,git log
看起来是这样的:
commit 7411ad0984841b28dca630d54c3b079ebd01c7e9 (HEAD -> master, feature)
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date: Tue Apr 7 13:58:09 2020 +0530
Second commit
commit 1750f9c5ba95f53742005657e9cee41390165dc7
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date: Tue Apr 7 13:57:54 2020 +0530
First commit
现在试试:
git reset --hard HEAD^
git checkout feature
git branch --set-upstream-to master
现在是 git 日志现在看起来:
commit 7411ad0984841b28dca630d54c3b079ebd01c7e9 (HEAD -> feature)
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date: Tue Apr 7 13:58:09 2020 +0530
Second commit
commit 1750f9c5ba95f53742005657e9cee41390165dc7 (master)
Author: Deepak Gupta <deepakguptacse@gmail.com>
Date: Tue Apr 7 13:57:54 2020 +0530
First commit
当我尝试 git rebase
时会发生什么?我觉得状态应该保持不变。
但它变为:
commit 1750f9c5ba95f53742005657e9cee41390165dc7 (HEAD -> feature, master)
Author: Deepak Gupta <deepak.gupta@rubrik.com>
Date: Tue Apr 7 13:57:54 2020 +0530
First commit
(END)
有人可以解释这种行为吗?
这个问题——或者说 特征,因为 Git 人喜欢提到它——是由于 Git 的 叉点模式。 The git rebase
documentation 描述如下:
If
upstream
is not specified, the upstream configured inbranch.<em>name</em>.remote
andbranch.<em>name</em>.merge
options will be used (see git-config[1] for details) and the--fork-point
option is assumed. If you are currently not on any branch or if the current branch does not have a configured upstream, the rebase will abort.
(格式,尤其是粗体部分,是我的)。下一段提供了这个神秘的摘要:
All changes made by commits in the current branch but that are not in
upstream
are saved to a temporary area. This is the same set of commits that would be shown bygit log <upstream>..HEAD
; or bygit log 'fork_point'..HEAD
, if--fork-point
is active (see the description on--fork-point
below); or bygit log HEAD
, if the--root
option is specified.
(此描述省略了一些重要的项目:特别是,默认情况下也丢弃了等效于补丁 ID 的合并和提交。但这些都不会影响您的特定情况。)
分叉点描述在页面的中途。它提到:
fork_point
is the result ofgit merge-base --fork-point <upstream> <branch>
command (see git-merge-base[1]). Iffork_point
ends up being empty, theupstream
will be used as a fallback.
upstream
是master
,branch
是当前分支,feature
。在我的存储库中,我现在 运行:
$ git merge-base --fork-point master feature
af07c3c48ff0d499400ac539aa9c665a8dddcd6f
(使用我在复制您的示例时创建的存储库中的哈希 ID)。让我们在我的存储库上使用 git log
来查看两个提交:
$ git log --decorate --oneline
af07c3c (HEAD -> feature) Second commit
dbf1741 (master) First commit
因此,鉴于 git merge-base --fork-point
的输出,rebase
承诺它将复制的提交是 git log af07c3c48ff0d499400ac539aa9c665a8dddcd6f..HEAD
:
$ git log af07c3c48ff0d499400ac539aa9c665a8dddcd6f..HEAD
$
未列出任何提交,因此未复制任何提交。
如何解决问题
要禁用分叉点模式,运行:
git rebase --no-fork-point
或:
git rebase master
即使当前分支 feature
的上游是 master
,一个 explicit git rebase master
disables 默认叉点模式。在使用明确的分支名称时强制 Git 使用分叉点模式——如果你想这样做的话;在这种情况下,您可能不想要它——您也可以运行:
git rebase --fork-point master
完全没有任何参数,你会得到 git rebase --fork-point master
的效果。