从另一个分支在Git中创建一个分支

我有两个分支:大师开发

我想从开发分支创建一个“功能分支”。

目前在分支开发上,我做:

git checkout -b myfeature dev

(一些工作)

git commit -am "blablabla"git push origin myfeature

但是,在看到我的树枝后,我得到了:

--**master**------0-----0-----0-----0-----0------------------------**dev**----**myfeature**

我的意思是分支似乎快进合并,我不明白为什么…

我做错了什么?

您如何从另一个分支分支并推回功能分支的远程存储库?

所有这些都在像这里描述的那个这样的分支模型中。

2390692 次浏览

如果您喜欢您发布的链接中的方法,请查看gitflow

这是他为该工作流程创建的一组脚本。

但要回答你的问题:

git checkout -b myFeature dev

开发创建MyFeature分支。做你的工作,然后

git commit -am "Your message"

现在将您的更改合并到开发,而无需快进

git checkout devgit merge --no-ff myFeature

现在将更改推送到服务器

git push origin devgit push origin myFeature

你会看到你想要的。

dev分支上同时工作。在你的场景中,特征分支从开发分支的尖端向前移动,但开发分支没有变化。作为直线绘制更容易,因为它可以被认为是向前运动。你到达了开发上的A点,从那里你只是继续沿着平行的路径前进。这两个分支并没有真正分叉。

现在,如果您在开发上进行提交,在合并之前,您将再次从相同的提交A开始,但现在功能将转到C,开发转到B。这将显示您尝试可视化的拆分,因为分支现在已经分歧。

*-----*Dev-------*Feature

Versus

       /----*DevB*-----*DevA\----*FeatureC

如果您想从Git中的任何现有分支创建一个新分支,只需按照选项进行操作。

首先更改/签出到要创建新分支的分支。例如,如果您有以下分支,如:

  • 大师
  • 开发
  • 分支1

因此,如果您想在名为"分支1"的分支下创建一个名为"subbranch_of_b1"的新分支,请按照以下步骤操作:

  1. 结帐或更改为"分支1"

     git checkout branch1
  2. 现在使用以下命令在"分支1"下创建名为“subbranch_of_b1”的新分支。

     git checkout -b subbranch_of_b1 branch1

    上面将在分支分支1下创建一个名为subbranch_of_b1的新分支(请注意,上面命令中的branch1不是强制性的,因为HEAD当前指向它,如果您在不同的分支上,您可以精确定位它)。

  3. 现在使用subbranch_of_b1后,您可以在本地或远程提交、推送或合并它。

在另一个分支下创建分支的示例图形说明

subbranch_of_b1推到远程:

 git push origin subbranch_of_b1

创建一个分支

  • 签出master分支时创建分支。这里master中的提交将同步到您创建的分支。

    git branch branch1

  • 签出分支1时创建分支。这里分支1中的提交将同步到分支2git branch branch2


签出一个分支

git签出命令切换分支或恢复工作树文件

  • git checkout branchname

重命名分支

  • git branch -m branch1 newbranchname

删除分支

  • git branch -d branch-to-delete
  • git branch -D branch-to-delete强制删除而不检查合并状态

创建和切换分支

  • git checkout -b branchname

完全包含的分支

  • git branch --merged


分支差异[git diff分支1…分支2]

多线差分

  • git diff master..branch1

单线差异

  • git diff --color-words branch1..branch2

为了从另一个分支创建分支,也可以使用以下语法:

git push origin refs/heads/<sourceBranch>:refs/heads/<targetBranch>

比"git check out-b"+"git ush的来源"短一点

Git 2.23引入了#0#1来拆分git checkout的职责。

从Git 2.23开始从现有分支创建新分支:

git switch -c my-new-branch

切换到一个新的分支'my-new'

  • -c--创建的缩写,取代了众所周知的git签出

请看这篇GitHub博客文章更详细地解释了这些变化:

Git 2.23为现有的套件带来了一对新的实验命令1:git开关git恢复。这两个是为了最终为众所周知的git签出提供更好的接口。新的命令打算每个都有一个明确的分离,整齐地分配git签出的许多职责

如果您想从另一个分支创建分支,请按照以下步骤操作:

假设

  1. 您目前在大师分支中。
  2. 您没有要提交的更改。(如果您有任何更改要提交,请将其隐藏起来!)
  3. BranchExisting是分支的名称,您需要从中创建一个名称为BranchMyNew的新分支。

步骤

  1. 将分支获取到本地机器。

    git fetch origin BranchExisting : BranchExisting

此命令将在本地创建一个具有相同分支名称的新分支。

  1. 现在,从大师分支签出到新获取的分支

    git checkout BranchExisting
  2. 您现在处于布兰奇现有中。现在从这个现有分支创建一个新分支。

    git checkout -b BranchMyNew

这是你的!

要从本地目录中的另一个分支创建分支,您可以使用以下命令。

git checkout -b <sub-branch> branch

例如:

  • 要创建的新分支的名称是“XYZ”
  • 分支的名称“ABC”,必须在其下创建“XYZ”
git checkout -b XYZ ABC

从另一个分支在Git中创建分支的各种方法:

这个答案增加了一些额外的洞察力,没有出现在现有的答案中,只是关于问题本身的标题从另一个分支在Git中创建一个分支),但没有确实解决了问题的更狭隘的细节,这些细节在这里已经有了足够的答案。

我添加这个是因为我真的需要知道如何做到下面的#1(从我没有签出的分支创建一个新分支),而且不清楚如何做到这一点,谷歌搜索导致这里作为热门搜索结果。所以,我会在这里分享我的发现。如果有的话,这没有被这里的任何其他答案触及。

当我在做的时候,我还将在下面添加我在常规工作流程中使用的其他最常见的git branch命令。

1.要从您<强>不签出的分支创建一个新分支:

当您签出任何分支时,从branch1创建branch2(例如:假设您签出了master):

git branch branch2 branch1

一般格式为:

git branch <new_branch> [from_branch]

man git branch显示如下。我所说的<new_branch>是他们所说的<branchname>,我所说的[from_branch]是他们所说的[<start-point>]

git branch [--track | --no-track] [-l] [-f] <branchname> [<start-point>]

2.要从您<强>做签出的分支创建一个新分支:

git branch new_branch

这对于在重设基址、压缩、硬重置等之前进行备份非常有用——在做任何可能严重扰乱你的分支的事情之前。

示例:我在feature_branch1上,我要使用git rebase -i master将20次提交压缩为1。如果我想“撤消”这个,让我们先备份这个分支!我这样做所有的…时间,发现它非常有帮助和安慰,知道我可以随时容易返回这个备份分支并重新分支,以防我在过程中搞砸feature_branch1

git branch feature_branch1_BAK_20200814-1320hrs_about_to_squash

20200814-1320hrs部分是格式YYYYMMDD-HHMMhrs中的日期和时间,因此是2020年8月14日13:20小时(下午1:20)。这样,我就有了一个简单的方法来找到我的备份分支,直到我确定我准备好删除它们。如果你不这样做并且搞砸了,你必须使用git reflog在搞砸之前找到你的分支,这要困难得多,压力更大,也更容易出错。

感叹词:关于git checkout vsgit switch的注释

  1. 经典的,通用的“瑞士军刀”,可以做1000件事:git checkout
  2. 新的和实验性的替代命令git checkoutgit switch+git restore

#0是最近在Git v2.23中添加的。使用#1查看您的git版本。它被设计为#2的极其有限的形式,仅设计为切换分支,而不是像git checkout那样能够签出或恢复文件。在这里阅读更多:https://www.git-tower.com/learn/git/commands/git-switch.

另请参阅:git Switch引入后git Checout还能做什么?git restore提供了git switch不包含的git checkout的其余部分功能。

man git switchman git restore警告:

这个命令是实验性的。行为可能会改变。

所以,如果你愿意,可以随意坚持使用git checkout。它的行为不太可能改变。

我自己几乎只使用git checkout,但如果您愿意,欢迎使用git switch(和git restore来恢复或“签出”文件)。

3.要从您<强>做签出的分支创建并检查一个新分支:

# the standard, "classic" command most people still use; `-b` stands# for "create 'b'ranch"git checkout -b new_branch
# the newer, "experimental" command now available as of Git v2.23; `-c` stands# for "'c'reate branch"git switch -c new_branch

为了清楚地说明那里发生了什么,要知道上面的这个命令等价于这些两个个单独的命令:

# classicgit branch new_branchgit checkout new_branch
# OR: new/experimental as of Git v2.23git branch new_branchgit switch new_branch

4.要从没有签出的分支创建并检查个新分支:

# classicgit checkout -b new_branch from_branch
# OR: new/experimental as of Git v2.23git switch -c new_branch from_branch

为了清楚地说明那里发生了什么,要知道上面的这个命令等价于这些个单独的命令:

# classicgit checkout from_branchgit branch new_branchgit checkout new_branch
# OR: new/experimental as of Git v2.23git switch from_branchgit branch new_branchgit switch new_branch

5.重命名分支

就像重命名终端中的常规文件或文件夹一样,git认为“重命名”更像是“m”ove命令,因此您使用git branch -m重命名分支。这是一般格式:

git branch -m <old_name> <new_name>

man git branch显示如下:

git branch (-m | -M) [<oldbranch>] <newbranch>

示例:让我们将branch_1重命名为branch_1.5

git branch -m branch_1 branch_1.5

或者,如果您已经签出了branch_1,您可以将当前签出分支重命名为branch_1.5,如下所示:

git branch -m branch_1.5

6.当您当前签出feature1时,根据main上的最新上游更改创建一个新功能分支(feature2

让我们把上面学到的很多东西放在一起,给出一个非常常见的例子,每当我们完成一个功能并需要启动另一个功能时,我们都需要运行。

# The beginner/intermediate way
git checkout main           # check out main branchgit pull                    # pull latest upstream changes downgit checkout -b feature2    # create branch `feature2` from `main`, and check# it out, all in one step`
# The advanced way
# [this is what I do--I'll explain why, below]git fetch origin main:main      # pull latest upstream changes down from the# remote `main` branch, to the# locally-stored remote-tracking **hidden**# branch named `origin/main`, **and** to# the local `main` branchgit checkout -b feature2 main   # create branch `feature2` from `main`, and# check it out, all in one step`
# OR (nearly the same thing)git fetch origin main           # pull latest upstream changes down from the# remote `main` branch, to the# locally-stored remote-tracking **hidden**# branch named `origin/main`. This does NOT# update the local `main` branch though!git checkout -b feature2 origin/main # create branch `feature2` from# `origin/main`, and check it out, all# in one step`

所以,当我在分支feature1上,并且刚刚完成它并准备好开始基于最新的main分支的新feature2时,我为什么要这样做:

git fetch origin main:maingit checkout -b feature2 main

而不是这个:

git checkout maingit pullgit checkout -b feature2

令人惊讶的是,答案是git checkout可以是git lfs0——在一个巨大的单仓存储库上占用git lfs1,在存储库的.git/hooks/post-checkout文件中使用git lfs2后签出挂钩。让我解释一下。.git/hooks/post-checkout文件是一个可执行文件,包含一个脚本,每次运行git checkout后git都会运行该脚本。如果它包含对git lfs post-checkout "$@"的调用,那么它可能会在运行一个看起来无辜的git checkout后尝试下载git lfs数据中的git lfs3(特定于我工作的存储库——你的场景可能会有所不同)。我不想这样做!所以,我跳过git checkout过程以避免麻烦,并立即开始我的feature2分支git lfs4下载所有我不需要的东西!

另见:

  1. 快速链接到我经常引用的我的答案,并认为是“git基础”:
    1. 在git中从另一个分支创建分支的各种方法
    2. 关于在git中检查文件或目录的所有内容
    3. 根据Git,谁是"我们",谁是"他们"?
    4. 如何通过--diff-filter=使用git diff过滤器
    5. 如何使用git lfs作为基本用户:git lfs fetchgit lfs fetch --allgit lfs pull有什么区别?

切换到开发分支:

git checkout develop

创建开发功能/foo分支。

git checkout -b feature/foo develop

合并变更进行开发,无需快进

git checkout developgit merge --no-ff myFeature

现在将更改推送到服务器:

git push origin developgit push origin feature/foo

这对我很有效:

转到github存储库,并选择要从中创建新分支的分支名称,如下图所示:

图像2

然后键入要创建的分支名称,然后单击创建分支

图像2