git从源分支拉入时出现奇怪问题

git从源分支拉入时出现奇怪问题,git,Git,我的一位同事将一家分行(BranchA)推到回购协议上 然后,我从BranchA创建了这个分支(testBranch)的副本 一切都很好 这位同事接着又向布兰卡提出了两项承诺 然后我有git pull(从回购中获取最新的变更) 但是,我没有看到提交的两个文件 回购 布兰卡 本地 git checkout master git pull git checkout testBranch origin/BranchA git merge master 我不确定为什么看不到最新的提交(文件) 解决方法

我的一位同事将一家分行(BranchA)推到回购协议上

然后,我从BranchA创建了这个分支(testBranch)的副本

一切都很好

这位同事接着又向布兰卡提出了两项承诺

然后我有git pull(从回购中获取最新的变更)

但是,我没有看到提交的两个文件

回购

布兰卡

本地

git checkout master
git pull
git checkout testBranch origin/BranchA
git merge master
我不确定为什么看不到最新的提交(文件)

解决方法:

  • 删除本地分支
  • 创建了一个新的分支
  • 收银台主机
  • 吉特拉力
  • 结帐新分行
  • git合并
  • 我现在看到另外两项承诺

  • 我觉得我好像错过了一步?感觉很奇怪,每次我需要从特定的源/分支获取最新的更改时,我都必须删除该分支

    您已经从
    BranchA
    创建了一个新分支
    testBranch
    。而您的同事将更改推到了
    BranchA
    。但您仍然在
    testBranch
    。因此,您的远程分支没有要拉取的更改,这就解释了为什么在
    testBranch
    中看不到
    BranchA
    中的提交

    ...--o--o--*            <-- BranchA
    

    ..--o--o--*您已经从
    BranchA
    创建了一个新分支
    testBranch
    。而您的同事将更改推到了
    BranchA
    。但您仍然在
    testBranch
    。因此,您的远程分支没有要拉取的更改,这就解释了为什么在
    testBranch
    中看不到
    BranchA
    中的提交

    ...--o--o--*            <-- BranchA
    

    …--o--o--*您将太多的魔力归于分支。:-)

    Git的工作方式非常简单。分支名称只是一个Git提交哈希ID的名称(我还建议您忘记,
    Git pull
    甚至存在,但我们很快就会看到它是什么,以及如何使用它)

    关于提交、哈希ID、分支名称和提交链 让我们稍微讨论一下这些提交哈希ID。散列ID是一大串难看的字母和数字,例如
    0d0ac3826a3bbb9247e39e12623bbcfdd722f24c
    。这唯一地标识了一些Git对象,通常是一个提交,当我们使用分支名称时,它肯定是一个提交。每个提交都记录其父提交或前置提交的哈希ID。这允许Git将提交串成一个向后看的链

    这意味着我们可以绘制这些提交链。如果我们让一个大写字母代表一个丑陋的大哈希ID,我们会得到如下结果:

    ... <-F <-G <-H   <--master
    
    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch (HEAD), BranchA
                     \
                      K--L   <-- origin/BranchA
    
    现在Git只需将
    I
    的散列ID写入
    master
    名称中,这样
    master
    现在就指向
    I

    ...--F--G--H--I   <-- master
    
    (稍后我们将进一步讨论远程跟踪名称。它们有点像分支名称,但有点扭曲。)

    当您创建一个新的分支名称时,Git所要做的就是使新名称指向某个现有的提交。例如,现在让我们使用git checkout BranchA创建自己的
    BranchA
    :1

    如果您现在创建一个新的提交,您的Git需要知道更新哪个分支名称。因此,您的Git有一个特殊的名称,
    HEAD
    ,用所有大写字母写成。2 Git将此名称附加到您的一个分支名称上:

    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch (HEAD), BranchA, origin/BranchA
    
    您的Git将在
    源代码下列出的URL处调用他们的Git,并询问他们的Git关于分支的信息。他们会说:哦,当然,给你:我的
    master
    是,我的
    BranchA
    是。(要查看这一点,请运行
    git ls remote origin
    ,这与
    git fetch origin
    类似,只是在获取远程名称和哈希列表后,它只打印出来。)

    有了这个列表,您的Git会继续要求他们的Git提交您没有的任何新提交。因此,如果他们已经更新了他们的
    BranchA
    ,您将得到他们的新提交。然后,不管发生了什么,Git现在设置所有以
    origin/
    开头的远程跟踪名称。也就是说,假设他们有两个新的提交。您自己的存储库现在如下所示:

    ... <-F <-G <-H   <--master
    
    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch (HEAD), BranchA
                     \
                      K--L   <-- origin/BranchA
    
    git合并之前
    ,我们的存储库中有以下内容:

    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch, BranchA (HEAD)
                     \
                      K--L   <-- origin/BranchA
    
    现在,commit
    L
    作为当前提交,commit
    L
    将填充索引和工作树。是时候谈谈这两个人了

    索引和工作树 我们已经提到,存储在提交中的文件是完全、完全、100%冻结/只读的。它们以一种特殊的、压缩的、仅限Git的格式存储。这让Git可以节省大量空间,并重用未更改的文件:如果新提交的文件与上一次提交的文件基本相同,则无需保存所有文件。旧提交的副本已冻结,因此新提交只能共享它们。(这个过程的细节在这里并不重要,但Git使用哈希ID(Git称之为blob对象)来实现这个技巧。)

    这对Git来说很好,但我们不能使用冻结的压缩Git文件来做任何其他事情。因此Git必须将冻结的文件解冻并反压缩为正常的日常形式,以便我们和计算机上的其他程序能够使用它们

    解冻后的文件进入工作树,这被称为工作树,因为我们在那里处理它们。在这里,我们可以用我们的文件做任何我们想做的事情。因此,对于每个文件,当前提交中有一个冻结副本,工作树中有一个解冻副本。(在其他提交中也可能存在冻结副本,但当前提交中的副本最有趣,因为我们可以并且经常将其与工作树中的副本进行比较。)

    索引,也称为暂存区,有时也称为缓存,是Git特有的东西。其他版本控制系统也冻结了提交
    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch (HEAD), BranchA, origin/BranchA
    
    git fetch origin
    
    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch (HEAD), BranchA
                     \
                      K--L   <-- origin/BranchA
    
    git checkout BranchA
    git merge origin/BranchA
    
    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch, BranchA (HEAD)
                     \
                      K--L   <-- origin/BranchA
    
    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch
                     \
                      K--L   <-- BranchA (HEAD), origin/BranchA
    
    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch
                     \
                      K--L   <-- BranchA (HEAD), origin/BranchA
    
    git checkout testBranch
    git merge <anything that identifies commit L>
    
    ...--F--G--H   <-- master, origin/master
                \
                 I--J
                     \
                      K--L   <-- testBranch, BranchA, origin/BranchA
    
    ...--F--G--H   <-- master, origin/master
                \
                 I--J   <-- testBranch (HEAD)
                     \
                      K--L   <-- origin/BranchA
    
    $ git clone <url>
    $ cd <repository>
    $ git checkout -b testBranch origin/BranchA
    ... wait until colleague updates origin/BranchA ...
    $ git fetch                      # defaults to using origin
    $ git merge origin/BranchA
    
    git pull origin master
    
    git fetch origin master
    git merge -m "merge branch 'master' of $url" origin/master