`git checkout -b newbranch upstream/newbranch` 和 `git checkout newbranch` 之间的区别
Difference between `git checkout -b newbranch upstream/newbranch` and `git checkout newbranch`
我已经阅读了 -b
的 this answer about importing an upstream branch into a fork. The answer suggests using git checkout -b newbranch upstream/newbranch
to switch to the new branch. I always just used git checkout newbranch
in this case and it worked aswell. Is there any difference between these commands? My guess is that I only need -b
to specify a branch name in case it should be different from upstream/newbranch
. But if I just want the branch with its original name newbranch
, is there any difference between using git checkout -b newbranch upstream/newbranch
and git checkout newbranch
? I have read the docs,但这并没有真正回答我的问题。
-b
命令创建一个新分支并签出。而 git checkout branch
检查一个已经存在的分支。请注意,如果您已经在本地跟踪了 newbranch
,那么 git checkout -b newbranch
或 git checkout -b newbranch upstream/newbranch
将引发错误。
例如。假设您没有名为 random
的分支。然后下面报错:
git checkout random
但这会创建并检出 random
:
git checkout -b random
相反,如果您有一个名为 random
的分支,第一个命令会将您切换到随机分支,而第二个命令将引发错误。
现有的答案没有确切它是如何工作的,这有点复杂。在内部,Git 调用这个东西 DWIM 模式。
Long-ish: 背景
让我们从这个开始:您的分支名称是您的。其他一些 Git 可能有一个名为 newbranch
或 branch2
或其他名称的分支,但如果您没有该分支名称,您就没有该分支名称。好吧,还没有 。
还请记住,每个提交都有一个唯一的哈希 ID。要查看当前提交的哈希 ID,运行:
git rev-parse HEAD
特殊名称HEAD
总是命名当前提交(通常也命名当前分支名称,但我们稍后再说)。 git rev-parse
命令会给你一个丑陋的大哈希 ID——对人类来说不是那么有用,但对 Git 至关重要,因为哈希 ID 是 Git 实际找到提交的方式。
同时,每个分支名称只包含一 (1) 个提交哈希 ID。如果你有一个分支名称master
,你可以通过运行ninggit rev-parse master
找到这个名称代表的哈希ID。和以前一样,git rev-parse
将名称变成丑陋的大哈希 ID。
现在,这意味着要创建一个 new 分支名称,您告诉 Git: 创建一个新的分支名称。这是要存储在其中的哈希 ID:_______。您告诉 Git 的 方法 是使用各种命令中的任何一个:
git 分支 <em>newname</em>
:这告诉 Git 创建新名称使用通过将 HEAD
解析为哈希 ID 找到的哈希 ID。
git 分支 <em>newname</em> <em>hash-id</em>
:这告诉 Git 使用您输入的散列 ID 创建新名称。散列 ID 很难输入,因此您可能会使用鼠标剪切和粘贴一个。但您不必这样做,因为:
git分支<em>newname</em><em>any-other-name-that-works-with-rev-parse</em>
: Git 运行 git rev-parse
在 last 名称上,找到哈希 ID,然后创建分支,使其包含你给它的哈希 ID。
git checkout -b <em>name</em>
and git checkout -b <em>name</em> <em>start-point</em>
:这些与使用 git branch
后跟 [= 非常相似330=]宁git checkout
.
但是还有一种方法可以创建 new 分支名称,那就是 运行 git checkout <em>name-that-does-not-yet-exist</em>
.
通常,如果您执行 git checkout supercalifragialistic
之类的操作,您只会得到一个错误:Git 尝试将该名称转换为哈希 ID(使用 git rev-parse
的内部等效项)这完全失败了,整个事情因错误而停止。但是 git checkout
内置了一个特殊的技巧。
现在,除了 branch names,Git 支持我称之为 remote-tracking names (Git 称它们为 remote-tracking 分支名称 但是这里的 branch 这个词有点误导,所以我认为最好保留它出去)。这些非常简单,真的:当你告诉它时,你的 Git 连接到其他 Git。您可能将其称为 Git origin
,因为这是标准名称。您偶尔会 运行 git fetch origin
或 git pull origin master
或类似的名称:名称 origin
这是您的 Git 找到 URL 用于调用的方式另一个 Git.
另一个 Git,在 origin
,有分支名称。 你的 Git 记住他们的分支名称,但因为你的名字是你的,所以你的Git记住他们的别名。这些是 remote-tracking 个名字。您的 Git 将他们的 master
重命名为您的 origin/master
,将他们的 xyz
重命名为 origin/xyz
,依此类推。
在你的问题中你谈到了upstream/newbranch
。名称 upstream
是 second Git 存储库的标准名称,您使用 git remote add
添加。你与之交谈的每个“其他Git”都有一个名字,remote-tracking名字有远程名字,后面是另一个Git' s branch 名称,它们之间有一个斜杠。所以你可能会同时得到 origin/newbranch
和 upstream/newbranch
,这很重要。
DWIM 模式
当你运行一个git checkout
,会出错,因为你没有分支,git checkout
会尝试一个新的在真正失败之前把戏。
您的 Git 将扫描 所有 个 remote-tracking 名称。例如,您可能有 origin/master
、origin/xyz
、upstream/xyz
和 upstream/newbranch
。
如果你已经有一个 master
和 运行 git checkout master
,那么 你 有一个 master
,所以这是git checkout
将使用。但是如果你 运行 git checkout newbranch
并且没有新分支,Git 将扫描以上所有内容。只有 upstream/newbranch
“看起来正确”,所以 Git 会自言自语:啊哈,如果我自动 create newbranch
upstream/newbranch
现在,我可以将 切换为 它! 这就是它的作用: 创建 这是一个新的分支,然后切换到它。假设是当你说切换到现有分支newbranch
时,你必须意味着创建新分支newbranch
来自 upstream/newbranch
。 Git 做你想做的,而不是你说的。
请注意,如果您 运行 git checkout xyz
,Git 有一个新问题:现在有 两个 候选人可以创建 xyz
。它可以从 origin/xyz
或 upstream/xyz
创建。默认情况下,DWIM 模式不会创建任何东西,您会看到错误。
(Git 2.21 及更高版本 --no-guess
可以完全禁用 DWIM。这主要用于 bash 完成脚本,如果你不想 Git猜测所有可能的 remote-tracking 个名字。)
其他几件重要的事情要知道
当你创建一个新的分支名称时,你可以Git设置它的upstream:
- 每个分支名称要么有一个上游,要么没有上游。
- 通常
master
的上游是 origin/master
,例如。
- 上游设置为您提供来自
git status
的更多信息,并让您 运行 git fetch
、git merge
、git rebase
和 git pull
无需再指定任何内容。所以这意味着方便。如果你觉得方便,就用它;如果没有,就不要。
要明确设置分支的上游,使用git branch --set-upstream-to
;要删除上游,请使用 git branch --unset-upstream
。当 git checkout
使用 DWIM 模式创建分支时,它通常会将该分支的上游设置为创建分支时使用的 remote-tracking 名称。您可以使用 git config
进行调整;参见 its documentation。
当使用git branch
或git checkout -b
时,可以明确告诉Git是否设置newly-created分支的上游,使用-t
或--track
选项(这些是相同的选项:一个只是更长的拼写)。请注意,在同时具有 origin/xyz
和 upstream/xyz
的棘手情况下,使用:
git checkout -t origin/xyz
是运行宁的short-hand方式:
git checkout -b xyz --track origin/xyz
也就是它:
- 指定在本地创建
xyz
时用于获取哈希 ID 的名称;
- 指定本地名称为
xyz
,因为使用的remote-tracking分支为origin/xyz
;和
- 指定新本地
xyz
应设置为 origin/xyz
作为其上游。
使用 git checkout -t upstream/xyz
的工作方式类似,除了您的新 xyz
使用通过解析 upstream/xyz
找到的提交 ID 并且您的新 xyz
具有 upstream/xyz
作为它的上游。
我已经阅读了 -b
的 this answer about importing an upstream branch into a fork. The answer suggests using git checkout -b newbranch upstream/newbranch
to switch to the new branch. I always just used git checkout newbranch
in this case and it worked aswell. Is there any difference between these commands? My guess is that I only need -b
to specify a branch name in case it should be different from upstream/newbranch
. But if I just want the branch with its original name newbranch
, is there any difference between using git checkout -b newbranch upstream/newbranch
and git checkout newbranch
? I have read the docs,但这并没有真正回答我的问题。
-b
命令创建一个新分支并签出。而 git checkout branch
检查一个已经存在的分支。请注意,如果您已经在本地跟踪了 newbranch
,那么 git checkout -b newbranch
或 git checkout -b newbranch upstream/newbranch
将引发错误。
例如。假设您没有名为 random
的分支。然后下面报错:
git checkout random
但这会创建并检出 random
:
git checkout -b random
相反,如果您有一个名为 random
的分支,第一个命令会将您切换到随机分支,而第二个命令将引发错误。
现有的答案没有确切它是如何工作的,这有点复杂。在内部,Git 调用这个东西 DWIM 模式。
Long-ish: 背景
让我们从这个开始:您的分支名称是您的。其他一些 Git 可能有一个名为 newbranch
或 branch2
或其他名称的分支,但如果您没有该分支名称,您就没有该分支名称。好吧,还没有 。
还请记住,每个提交都有一个唯一的哈希 ID。要查看当前提交的哈希 ID,运行:
git rev-parse HEAD
特殊名称HEAD
总是命名当前提交(通常也命名当前分支名称,但我们稍后再说)。 git rev-parse
命令会给你一个丑陋的大哈希 ID——对人类来说不是那么有用,但对 Git 至关重要,因为哈希 ID 是 Git 实际找到提交的方式。
同时,每个分支名称只包含一 (1) 个提交哈希 ID。如果你有一个分支名称master
,你可以通过运行ninggit rev-parse master
找到这个名称代表的哈希ID。和以前一样,git rev-parse
将名称变成丑陋的大哈希 ID。
现在,这意味着要创建一个 new 分支名称,您告诉 Git: 创建一个新的分支名称。这是要存储在其中的哈希 ID:_______。您告诉 Git 的 方法 是使用各种命令中的任何一个:
git 分支 <em>newname</em>
:这告诉 Git 创建新名称使用通过将HEAD
解析为哈希 ID 找到的哈希 ID。git 分支 <em>newname</em> <em>hash-id</em>
:这告诉 Git 使用您输入的散列 ID 创建新名称。散列 ID 很难输入,因此您可能会使用鼠标剪切和粘贴一个。但您不必这样做,因为:git分支<em>newname</em><em>any-other-name-that-works-with-rev-parse</em>
: Git 运行git rev-parse
在 last 名称上,找到哈希 ID,然后创建分支,使其包含你给它的哈希 ID。git checkout -b <em>name</em>
andgit checkout -b <em>name</em> <em>start-point</em>
:这些与使用git branch
后跟 [= 非常相似330=]宁git checkout
.
但是还有一种方法可以创建 new 分支名称,那就是 运行 git checkout <em>name-that-does-not-yet-exist</em>
.
通常,如果您执行 git checkout supercalifragialistic
之类的操作,您只会得到一个错误:Git 尝试将该名称转换为哈希 ID(使用 git rev-parse
的内部等效项)这完全失败了,整个事情因错误而停止。但是 git checkout
内置了一个特殊的技巧。
现在,除了 branch names,Git 支持我称之为 remote-tracking names (Git 称它们为 remote-tracking 分支名称 但是这里的 branch 这个词有点误导,所以我认为最好保留它出去)。这些非常简单,真的:当你告诉它时,你的 Git 连接到其他 Git。您可能将其称为 Git origin
,因为这是标准名称。您偶尔会 运行 git fetch origin
或 git pull origin master
或类似的名称:名称 origin
这是您的 Git 找到 URL 用于调用的方式另一个 Git.
另一个 Git,在 origin
,有分支名称。 你的 Git 记住他们的分支名称,但因为你的名字是你的,所以你的Git记住他们的别名。这些是 remote-tracking 个名字。您的 Git 将他们的 master
重命名为您的 origin/master
,将他们的 xyz
重命名为 origin/xyz
,依此类推。
在你的问题中你谈到了upstream/newbranch
。名称 upstream
是 second Git 存储库的标准名称,您使用 git remote add
添加。你与之交谈的每个“其他Git”都有一个名字,remote-tracking名字有远程名字,后面是另一个Git' s branch 名称,它们之间有一个斜杠。所以你可能会同时得到 origin/newbranch
和 upstream/newbranch
,这很重要。
DWIM 模式
当你运行一个git checkout
,会出错,因为你没有分支,git checkout
会尝试一个新的在真正失败之前把戏。
您的 Git 将扫描 所有 个 remote-tracking 名称。例如,您可能有 origin/master
、origin/xyz
、upstream/xyz
和 upstream/newbranch
。
如果你已经有一个 master
和 运行 git checkout master
,那么 你 有一个 master
,所以这是git checkout
将使用。但是如果你 运行 git checkout newbranch
并且没有新分支,Git 将扫描以上所有内容。只有 upstream/newbranch
“看起来正确”,所以 Git 会自言自语:啊哈,如果我自动 create newbranch
upstream/newbranch
现在,我可以将 切换为 它! 这就是它的作用: 创建 这是一个新的分支,然后切换到它。假设是当你说切换到现有分支newbranch
时,你必须意味着创建新分支newbranch
来自 upstream/newbranch
。 Git 做你想做的,而不是你说的。
请注意,如果您 运行 git checkout xyz
,Git 有一个新问题:现在有 两个 候选人可以创建 xyz
。它可以从 origin/xyz
或 upstream/xyz
创建。默认情况下,DWIM 模式不会创建任何东西,您会看到错误。
(Git 2.21 及更高版本 --no-guess
可以完全禁用 DWIM。这主要用于 bash 完成脚本,如果你不想 Git猜测所有可能的 remote-tracking 个名字。)
其他几件重要的事情要知道
当你创建一个新的分支名称时,你可以Git设置它的upstream:
- 每个分支名称要么有一个上游,要么没有上游。
- 通常
master
的上游是origin/master
,例如。 - 上游设置为您提供来自
git status
的更多信息,并让您 运行git fetch
、git merge
、git rebase
和git pull
无需再指定任何内容。所以这意味着方便。如果你觉得方便,就用它;如果没有,就不要。
要明确设置分支的上游,使用git branch --set-upstream-to
;要删除上游,请使用 git branch --unset-upstream
。当 git checkout
使用 DWIM 模式创建分支时,它通常会将该分支的上游设置为创建分支时使用的 remote-tracking 名称。您可以使用 git config
进行调整;参见 its documentation。
当使用git branch
或git checkout -b
时,可以明确告诉Git是否设置newly-created分支的上游,使用-t
或--track
选项(这些是相同的选项:一个只是更长的拼写)。请注意,在同时具有 origin/xyz
和 upstream/xyz
的棘手情况下,使用:
git checkout -t origin/xyz
是运行宁的short-hand方式:
git checkout -b xyz --track origin/xyz
也就是它:
- 指定在本地创建
xyz
时用于获取哈希 ID 的名称; - 指定本地名称为
xyz
,因为使用的remote-tracking分支为origin/xyz
;和 - 指定新本地
xyz
应设置为origin/xyz
作为其上游。
使用 git checkout -t upstream/xyz
的工作方式类似,除了您的新 xyz
使用通过解析 upstream/xyz
找到的提交 ID 并且您的新 xyz
具有 upstream/xyz
作为它的上游。