为什么git branch在git reset之后仍显示早期分支--hard FETCH_HEAD(用于新分支)?

时间:2016-06-29 15:59:38

标签: git branch reset

我正在这个当地分公司工作。

然后我git fetch origin [new branch that only exists on remote repository]

然后我git reset --hard FETCH_HEAD

我相信我现在正在研究这个新分支的代码。 但是当我输入active时,我仍然看到早期的本地分支标记为git branch(带*)。我曾经认为git branch总是显示我正在研究的分支,但在我看来现在并非如此。 理解这一点的人可以分享他/她的理解吗?

1 个答案:

答案 0 :(得分:0)

你在这里使用了错误的命令。

首先,让我们注意单词" branch"很暧昧。它可以引用存储库中的数据结构,它是从提交开始并在历史记录中向后工作,或者它可以引用分支名称,这就是Git可以的方式找到分支数据结构的最尖端提交。也就是说,名称指向一个特定的提交,然后从该提交中,Git找到其父提交及其父项,依此类推:分支数据结构。另请参阅What exactly do we mean by "branch"?

git branch列出分支名称

你认为git branch向你显示你当前的分支是正确的:

$ git branch
  develop
  master
  revise
* target

星号*字符显示在当前分支的前面(如果您启用了颜色,则当前分支也显示为绿色,默认情况下,尽管您可以选择其他颜色)。 / p>

默认情况下,git branch专门显示本地(普通)分支名称。您可以使用git branch -r

向其询问远程跟踪分支
$ git branch -r
  origin/develop
  origin/master

甚至"所有"分支git branch -a

分支名称是缩写形式;全名拼写为refs/heads/masterrefs/heads/develop,依此类推。远程跟踪分支名称拼写为refs/remotes/,后跟远程名称,如origin,后跟另一个斜杠/,最后是分支的名称,如另一个Git存储库,位于遥控器上。

Git通常剥离本地分支的refs/heads/部分,以及远程跟踪分支的refs/remotes/部分。这就是我们在git branchgit branch -r输出中看到的内容。出于某种神秘的原因,git branch -a仅从远程跟踪分支中剥离refs/

$ git branch -a
  develop
  master
  revise
* target
  remotes/origin/develop
  remotes/origin/master

git checkout更改您所在的分支名称

虽然有许多并发症,git checkout是用于从一个分支切换到另一个分支的命令。

拥有本地分支后,您可以使用git checkout切换到它:

$ git checkout master
Switched to branch 'master'

等等。进入其他分支后,git status会说On branch master,而git branch会将星号放在master旁边。 1

  

我在[a]当地分公司工作。

     

然后我做git fetch origin [new branch that only exists on remote repository]

不要这样做。这并不是说你不能这样做,而是把它写出来就像是个坏主意。只需运行git fetch origin,即可将所有分支机构带入其中,然后将其复制到远程跟踪分支机构。以下是从git获取最新origin时会发生什么:

$ git fetch origin
remote: Counting objects: 1892, done.
remote: Compressing objects: 100% (1878/1878), done.
remote: Total 1892 (delta 1199), reused 16 (delta 12)
Receiving objects: 100% (1892/1892), 1.96 MiB | 2.23 MiB/s, done.
Resolving deltas: 100% (1199/1199), done.
From git://git.kernel.org/pub/scm/git/git
   05219a1..cf4c2cf  master     -> origin/master
   0b65a8d..2ff7dff  maint      -> origin/maint
 + 3dc84b0...38a2ea1 next       -> origin/next  (forced update)
 + b85345d...6eeae5c pu         -> origin/pu  (forced update)
   1ebf750..2b74c92  todo       -> origin/todo

这带来了五个分支,将它们复制到refs/remotes/origin/远程跟踪分支名称。如果我想要的只是master,那么带来一切的速度会慢一点,但另一方面,最终我可能想要一切,如果我现在把它全部拿来,我就不会有把它带到以后。

它也更容易,并且它确保我拥有所有远程跟踪分支,这使我能够选择正确的远程跟踪分支作为我的"上游"对于我所做的任何新的本地分支机构。

创建新的本地分支

如果您有远程跟踪分支,例如origin/newbranch,而您拥有与之对应的本地分支,则必须创建那个本地分支。

确保当地分支机构是一个好主意:

  1. 具有相同的名称(减去origin/部分,当然还有refs/heads/部分):在这种情况下,我们要创建本地分支newbranch;
  2. origin/newbranch版本同步(指向同一个提交);和
  3. origin/newbranch设置为上游
  4. 我们可以通过首先创建一个名为newbranch的本地分支,然后确保newbranch指向与origin/newbranch相同的branch-tip-commit来执行以下几个步骤:最后将newbranch的上游设置为origin/newbranch。这几乎就是你现在要做的事情(但是你使用了错误的命令,试图让这一切都发生在第2步)。

    现在我们有了远程跟踪分支,但是有一种更简单的方式:

    $ git checkout newbranch
    

    你可能会非常合理地说:"嘿!这使得毫无意义!"你是对的:没有名为newbranch 的本地分支,我们无法检查出来。然而,凭借我对Git本身的回购副本:

    $ git checkout maint
    Branch maint set up to track remote branch maint from origin.
    Switched to a new branch 'maint'
    

    这里发生的是git checkout从尝试检出本地分支maint开始,但发现它不存在。因此,它会查看我们所有的远程跟踪分支,并发现只有一个远程跟踪maint,即origin/maint。然后,它在一个命令中完成:

    1. 创建本地分支maint
    2. 指向与远程跟踪分支origin/maint
    3. 相同的提交 将origin/maint设置为上游的
    4. ,即在maint上跟踪origin
    5. 这是我们在邮件中看到的内容。

      (然后我实际上并不想要maint,所以我做了:

      $ git checkout master
      $ git branch -d maint
      

      摆脱它。)

      git reset很复杂而不是你想要的

      为了完整起见,让我们简要介绍一下git reset的作用。

      git checkout一样,只有一个命令填充了太多选项。但是,git reset作为其主要的 2 函数,具有更改当前分支指向的提交的效果。这绝对是你想在这里做什么。

      git reset命令也可以选择:

      • --mixed:重置Git" s" index" (也称为"临时区域",这通常是更好的名称)
      • --hard--mixed会删除工作树中正在进行的工作,将文件替换为重新设置到索引中的版本。

      git reset可以使用更多方法,其中一些需要分支更改为其当前值(即无效更改)。这些帮助让每个人都对git reset所做的事情感到困惑。这些可能应该是不同的Git命令,就像git checkout更危险的模式(覆盖文件)可能应该是来自git checkout的单独命令更安全(从不 - 失去进行中的工作)形式。

      1 在Git中,你总是" on" 一些分支。有时候,在做了git checkout之后,Git说你已经分离了HEAD"模式和"不在分支"。当你在这个"分离的HEAD"状态,你 实际上在各种分支上,但是:你是(单一的,特殊的)匿名(未命名)分支。你在这种状态下提出的都是暂时的,除非你为他们创造一个名字"很快就会#34;。 (&#34的定义;很快就会#34;可以留给不同的文章/问题/博客帖子/其他。)除非您处于git rebase的中间 - 和{ {1}}会告诉你你是否 - 如果你在"分离的HEAD"模式,您可能希望git status分支名称并退出此模式。

      git checkoutgit status都会告诉您是否处于此分离的HEAD状态。 git branch命令现在非常好(在Git 1.6版左右的旧时代,它不是那么好)并且是你经常使用的东西。

      2 我说这是&#34;主要&#34;效果是因为git status 总是更改当前分支,但通常情况下,我们会更改&#34;提交从现在的位置,到现在的位置,这不是一个非常有趣的变化&#34;。这是因为来自git resetgit reset的{​​{1}} 其他效果通常是我们想要的。如果我们让Git将当前分支从它所在的位置移动到它所在的位置,并同时执行其他一些操作,则效果就像它只执行其他操作一样。< / p>

      由于我们经常以这种方式使用git reset --mixed,因此可以将这些其他效果称为“主要&#34;同样 - 但实际上,它们是可选的,而分支移动效果总是会发生。只是如果你将分支机构从它所在的位置移动到它所在的位置,这就是移动&#34;非常无聊,容易忘记。