美文网首页
Git Day.5 Branch(2)

Git Day.5 Branch(2)

作者: DendiSe7en | 来源:发表于2016-09-20 18:03 被阅读0次

    上海这些天开始有了秋天的感觉,在我没有更新博客的日子里,已经感冒了一次,所以今年的感冒次数已经用完了。烦人的工作也暂告一段落,最最重要的是,中秋来了。然而假期总是比平时上班还忙。远在棒子国的小伙伴也回到了祖国母亲的怀抱,简直开心(主要是看他被他爸妈嫌弃我开心)。今天的任务就是把分支这章结束掉,其实之前来来回回已经看过很多遍了。一直没有时间写下来。


    • 分支管理
        比较简单的都直接贴上代码,不多做解释。

    1.查看分支:

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moreTestAboutGit (master)
    $ git branch -v #加上-v可以查看分支详情
    iss53  19c769e iss53.txt
    * master bd0cb0d [ahead 9] 
    Merge branch 'iss53' Test about the merging between two branches
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moreTestAboutGit (testing)
    $ git branch --merged#查看已合并分支
      iss53
      master
    * testing
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moreTestAboutGit (testing)
    $ git branch --no-merged#查看未合并分支
    

    2.新建,切换分支:
      其实在上一篇已经有提到新建和切换,直接贴代码

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moreTestAboutGit (master)
    $ git branch testing#新建分支
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moreTestAboutGit (master)
    $ git checkout testing#切换到新建的分支testing
    Switched to branch 'testing'
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moreTestAboutGit (master)
    $ git checkout -b testing#合并上面两步
    Switched to a new branch 'testing'
    

    3.删除分支:
      针对有未合并内容的,会有提醒

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moreTestAboutGit (master)
    $ git branch -d testing
    error: The branch 'testing' is not fully merged.
    If you are sure you want to delete it, run 'git branch -D testing'.
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moreTestAboutGit (master)
    $ git branch -D testing
    Deleted branch testing (was 272283b).
    

    没有未合并内容的,可以直接删除

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moreTestAboutGit (master)
    $ git branch -d testing
    Deleted branch testing (was bd0cb0d).
    

    • 分支在开发中的应用
        官方的文档中主要提到了两种管理分支的方式:
        因为无法描述得比原文更加详细,我直接摘录 原文
    • 长期分支
        "由于 Git 使用简单的三方合并,所以就算在较长一段时间内,反复多次把某个分支合并到另一分支,也不是什么难事。也就是说,你可以同时拥有多个开放的分支,每个分支用于完成特定的任务,随着开发的推进,你可以随时把某个特性分支的成果并到其他分支中。
        许多使用 Git 的开发者都喜欢用这种方式来开展工作,比如仅在 master
      分支中保留完全稳定的代码,即已经发布或即将发布的代码。与此同时,他们还有一个名为 develop或 next的平行分支,专门用于后续的开发,或仅用于稳定性测试 — 当然并不是说一定要绝对稳定,不过一旦进入某种稳定状态,便可以把它合并到 master
      里。
        这样,在确保这些已完成的特性分支(短期分支,比如之前的 iss53
      分支)能够通过所有测试,并且不会引入更多错误之后,就可以并到主干分支中,等待下一次的发布。
        本质上我们刚才谈论的,是随着提交对象不断右移的指针。稳定分支的指针总是在提交历史中落后一大截,而前沿分支总是比较靠前。(如下图) "

    "或者把它们想象成工作流水线,或许更好理解一些,经过测试的提交对象集合被遴选到更稳定的流水线"

    关于这种使用这种模式的建议:
      "你可以用这招维护不同层次的稳定性。某些大项目还会有个 proposed(建议)或 pu(proposed updates,建议更新)分支,它包含着那些可能还没有成熟到进入 next或 master 的内容。
      这么做的目的是拥有不同层次的稳定性:当这些分支进入到更稳定的水平时,再把它们合并到更高层分支中去。再次说明下,使用多个长期分支的做法并非必需,不过一般来说,对于特大型项目或特复杂的项目,这么做确实更容易管理。"

    • 特性分支
        并不绝对的说,特性分支会比长期分支能更适应不同的场景。
        下面也是引用一个官方的例子来说明:
        (因为本人水平有限,避免误导后看到的朋友,理论上的东西不多发表意见)

    (ProGit原文:经过重新分段)
        “现在我们来看一个实际的例子。请看下图 ,由下往上:
        1.起先我们在 master工作到 C1,然后开始一个新分支iss91 尝试修复 91 号缺陷,
        2.提交到 C6 的时候,又冒出一个解决该问题的新办法,
        3.于是从之前 C4 的地方又分出一个分支 iss91v2,
        4.干到 C8 的时候,又回到主干 master 中提交了 C9 和 C10,
        5.再回到 iss91v2 继续工作,提交 C11,
        6.接着,又冒出个不太确定的想法,从 master 的最新提交 C10 处开了个新的分支 dumbidea 做些试验。”

    "现在,假定两件事情:我们最终决定使用第二个解决方案,即 iss91v2 中的办法;另外,我们把 dumbidea分支拿给同事们看了以后,发现它竟然是个天才之作。
        所以接下来,我们准备抛弃原来的 iss91分支(实际上会丢弃 C5 和 C6),直接在主干中并入另外两个分支。最终的提交历史将变成下图这样:"



    • 远程分支
       1.推送分支
       远程分支,顾名思义,就是在服务器端的分支。如果脱离了仓库来描述一个分支,就显得毫无意义。所以远程分支的一般表现形式是:
                  (远程仓库名)/(分支名)

    这一章看了好几遍,却发现整篇都专注在远程分支的使用方式,连远程分支的查看都没提及:

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /d/GITREPOS/moretestaboutgit (master)
    $ git branch -a #查看远程分支
    * master
    remotes/origin/HEAD -> origin/master
    remotes/origin/master
    

    不难发现,我们得到的结果里面,有一个HEAD 这个就是之前提及到的HEAD的指针,表示你当前所在的分支。

    然后看下文档提供的例子:
      我们先从远程仓库,clone整个repos下来到我们本地,这时候git会在本地给我们自动创建一个名为origin的仓库 和master分支,当然你可以自定义仓库名。如图:

    这时候你本地的项目怎么狂暴改都没关系,因为你不提交到远程分支就没有任何影响,而如果在你修改本地内容的这段时间,服务器上的分支如果有更新。那么在你提交的时候,需要你先从服务器上同步最新的内容到本地,然后再提交。
      官方的文档也直接是这样做的,但是我觉得我有必要去试下能不能直接提交。(下面是作死的内容,没有兴趣可以跳过,我只是为了证明如果不同步远程分支上的最新内容,就无法提交本地分支到远程分支上。)

    首先,我在两个不同的目录clone同一个项目。分别是A和B。
      A目录:

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /d/GITREPOS
    $ git clone git@github.com:DendiSe7enGitHub/moreTestAboutGit.git
    Cloning into 'moreTestAboutGit'...
    remote: Counting objects: 12, done.
    remote: Total 12 (delta 0), reused 0 (delta 0), pack-reused 12
    Receiving objects: 100% (12/12), done.
    Resolving deltas: 100% (1/1), done.
    Checking connectivity... done.
    

    B目录:(这里出现这个提示是因为我B目录已经clone过这个项目了)

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH (master)
    $ git clone git@github.com:DendiSe7enGitHub/moreTestAboutGit.git
    fatal: destination path 'moreTestAboutGit' 
    already exists and is not an empty     directory.
    

    然后我在A目录,新建了一个文件(BranchTestFile.txt),然后push到远程分支master上

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /d/GITREPOS
    $ cd moretestaboutgit# 进入到新clone的本地仓库目录
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /d/GITREPOS/moretestaboutgit (master)
    $ git branch -a#查看当前本地和远程分支
    * master
      remotes/origin/HEAD -> origin/master
      remotes/origin/master
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /d/GITREPOS/moretestaboutgit (master)
    $ ls
    gitignore  readme.md  READMORE
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /d/GITREPOS/moretestaboutgit (master)
    $ vim BranchTestFile.txt    #创建文件BranchTestFile.txt
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /d/GITREPOS/moretestaboutgit (master)
    $ git add BranchTestFile.txt
    warning: LF will be replaced by CRLF in BranchTestFile.txt.
    The file will have its original line endings in your working directory.
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /d/GITREPOS/moretestaboutgit (master)
    $ git commit -m"Test Branch"#提交到本地
    [master adec571] Test Branch
     1 file changed, 1 insertion(+)
     create mode 100644 BranchTestFile.txt
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /d/GITREPOS/moretestaboutgit (master)
    $ git push origin master#将本地的修改push到远程分支上
    Counting objects: 3, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 292 bytes | 0 bytes/s, done.
    Total 3 (delta 1), reused 0 (delta 0)
    remote: Resolving deltas: 100% (1/1), completed with 1 local objects.
    To github.com:DendiSe7enGitHub/moreTestAboutGit.git
       9f012bb..adec571  master -> master
    

    这里有一点需要提一下,我用的git push origin master其实是简便的写法,完整的是:git push origin master:master 意思是,将本地master分支推送到远程仓库origin的master分支。
      然后现在远程分支master上,相对于我们之前clone的B分支来说,已经有了新的更新。也就是我刚刚通过A分支提交的代码。
      如果这时候我想要在B分支上也新建一个文件,然后提交到远程分支上,能提交么?试试看:

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH (master)
    $ cd moretestaboutgit#进入新clone的仓库目录
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (testing)
    $ vim testBranch2#创建一个文件 testBranch2
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (testing)
    $ git status#查看当前本地分支状态
    On branch testing
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    
            testBranch2
    
    nothing added to commit but untracked files present (use "git add" to track)
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (testing)
    $ git add testBranch2#将新添加的文件加到暂存区
    warning: LF will be replaced by CRLF in testBranch2.
    The file will have its original line endings in your working directory.
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (testing)
    $ git commit -m"Test Branch2"#提交更新到本地
    [testing 41672ca] Test Branch2
     1 file changed, 1 insertion(+)
     create mode 100644 testBranch2
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (testing)
    $ git push origin master#将当前本地分支推送到master上
    To github.com:DendiSe7enGitHub/moreTestAboutGit.git
     ! [rejected]        master -> master (fetch first)
    error: failed to push some refs to 'git@github.com:DendiSe7enGitHub/moreTestAboutGit.git'
    hint: Updates were rejected because the remote contains work that you do
    hint: not have locally. This is usually caused by another repository pushing
    hint: to the same ref. You may want to first integrate the remote changes
    hint: (e.g., 'git pull ...') before pushing again.
    hint: See the 'Note about fast-forwards' in 'git push --help' for details.
    

    不出意外的报错了。
      "Updates were rejected because the remote contains work that you do not have locally. This is usually caused by another repository pushing to the same ref. You may want to first integrate the remote changes (e.g., 'git pull ...') before pushing again. See the 'Note about fast-forwards' in 'git push --help' for details."
      "本次更新,因为远程分支包含你本地没有的工作项目而被拒绝。这通常由其他仓库提交的更新到同一个远程分支引起。你可能在再次推送之前,想要整合远程的改动。"
      然后解决的办法就是按照官方的文档说的,先fetch远程的分支数据到本地分支,再提交。

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (testing)
    $ git fetch origin
    remote: Counting objects: 8, done.
    remote: Total 8 (delta 2), reused 2 (delta 2), pack-reused 6
    Unpacking objects: 100% (8/8), done.
    From github.com:DendiSe7enGitHub/moreTestAboutGit
       7bd6f76..adec571  master     -> origin/master
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (testing)
    $ git push origin master
    To github.com:DendiSe7enGitHub/moreTestAboutGit.git
     ! [rejected]        master -> master (non-fast-forward)
    error: failed to push some refs to 'git@github.com:DendiSe7enGitHub/moreTestA   boutGit.git'
    hint: Updates were rejected because a pushed branch tip is behind its remote
    hint: counterpart. Check out this branch and integrate the remote changes
    hint: (e.g. 'git pull ...') before pushing again.
    hint: See the 'Note about fast-forwards' in 'git push --help' for details.
    

    竟然还是报错?我仔细查了下,原来当前的工作分支并不是本地的master而是testing分支。

    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (testing)
    $ git branch -v
      iss53   19c769e iss53.txt
      master  bd0cb0d [ahead 9, behind 3] Merge branch 'iss53' Test about the merging between two branches
    * testing 35256d3 Merge branch 'master' of github.com:DendiSe7enGitHub/moreTestAboutGit into testing
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (testing)
    $ git checkout master
    Switched to branch 'master'
    Your branch and 'origin/master' have diverged,
    and have 9 and 3 different commits each, respectively.
      (use "git pull" to merge the remote branch into yours)
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (master)
    $ git pull origin master
    From github.com:DendiSe7enGitHub/moreTestAboutGit
     * branch            master     -> FETCH_HEAD
    Merge made by the 'recursive' strategy.
     BranchTestFile.txt | 1 +
     readme.md          | 2 ++
     2 files changed, 3 insertions(+)
     create mode 100644 BranchTestFile.txt
     create mode 100644 readme.md
    
    Dendoink@QELRM4A8Y4JCC8E MINGW64 /e/GITPUSH/moretestaboutgit (master)
    $ git push origin master
    Counting objects: 25, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (21/21), done.
    Writing objects: 100% (25/25), 2.35 KiB | 0 bytes/s, done.
    Total 25 (delta 13), reused 0 (delta 0)
    remote: Resolving deltas: 100% (13/13), completed with 1 local objects.
    

    如果你是个细心的读者,肯定会发现我最后这次提交没有fetch 但是也提交成功了,而且我用了git pull这个命令。为什么呢,实际上 git pull 相当于 git fetch + git merge 然后我直接push 就成功了。到了这里其实才刚刚结束推送分支这块的内容。

    作为一个推送者,我们的工作结束了,那如果我们是那个被动接收的人呢?面对一个新的分支,你有两种选择

    • 合并到当前本地分支

      $ git fetch origin
      $ git merge origin/serverfix
      
    • 整个新分支作为新的本地分支
      $ git checkout -b serverfix origin/serverfix

    (接下来这两段直接引用原文)
     2.跟踪远程分支
      从远程分支 checkout出来的本地分支,称为 跟踪分支 (tracking branch)。
      跟踪分支是一种和某个远程分支有直接联系的本地分支。在跟踪分支里输入 git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。
      同样,在这些分支里运行 git pull 会获取所远程索引,并把它们的数据都合并到本地分支中来。
      在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是 git push 和 git pull 一开始就能正常工作的原因。当然,你可以随心所欲地设定为其它跟踪分支:
      比如 origin 上除了 master之外的其它分支。刚才我们已经看到了这样的一个例子:git checkout -b [分支名] [远程名]/[分支名]。如果你有 1.6.2 以上版本的 Git,还可以用 --track 选项简化:

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

    要为本地分支设定不同于远程分支的名字,只需在第一个版本的命令里换个名字:

    $ git checkout -b sf origin/serverfix
    Branch sf set up to track remote branch serverfix from origin.
    Switched to a new branch 'sf'
    

    3.删除远程分支
      如果不再需要某个远程分支了,比如搞定了某个特性并把它合并进了远程的 master分支(或任何其他存放稳定代码的分支),可以用这个非常无厘头的语法来删除它:git push [远程名] :[分支名]。如果想在服务器上删除serverfix 分支,运行下面的命令:

    $ git push origin :serverfix
    To git@github.com:schacon/simplegit.git 
    - [deleted] serverfix
    

    咚!服务器上的分支没了。你最好特别留心这一页,因为你一定会用到那个命令,而且你很可能会忘掉它的语法。有种方便记忆这条命令的方法:记住我们不久前见过的 git push [远程名] [本地分支]:[远程分支] 语法,如果省略 [本地分支],那就等于是在说“在这里提取空白然后把它变成[远程分支]”。


    • 分支衍合
      留到明天吧。

    相关文章

      网友评论

          本文标题:Git Day.5 Branch(2)

          本文链接:https://www.haomeiwen.com/subject/mfwjettx.html