zoukankan      html  css  js  c++  java
  • Git远程分支和refs文件具体解释

    近期同一时候同步博客到github和gitcafe上,遇到一些问题,我们分例如以下几个方面来分析一下:

    推送远程分支到同一个server

    比方首先建立gitserver,顺便clone出两个副本

    mkdir server
    cd server
    git init --bare
    cd ..
    git clone server git1
    git clone server git2

    眼下git branch是空的。

    我们提交一点东西建立master分支。

    cd git1
    touch a.txt
    git add .
    git commit -m "init"
    git push origin master

    如今git branch -a 显示:

    * master
      remotes/origin/master

    当前系统处于master分支,远程origin的repository上也有一个master分支。两个是tracking的。

    我们切到git2以下

    cd ../git2
    git pull origin

    这时候git2跟git1全然同步了。

    如今我们開始尝试建立还有一个分支并推送到server。

    习惯的,我们还是切回git1

    cd ../git1
    git checkout -b source

    这时候我们已经有了一个本地分支了,假设这个分支不须要共享,那么你能够一直在这个分支上commit可是不push到server。直到这个分支被合并回主分支或者丢弃。

    git branch 显演示样例如以下:

      master
    * source

    我们终于决定把这个分支push到server上与其它人共享。例如以下:

    git push origin source:source

    这时候git branch -a 能看到当前repository里面全部的分支,包含两个本地的,两个远程的,本地和远程的都处于tracking状态。

      master
    * source
      remotes/origin/master
      remotes/origin/source

    切到还有一个副本。

    cd ../git2
    git pull origin

    显演示样例如以下:

     * [新分支]          source      -> origin/source

    git branch -a显示本地已经有了一个远程分支的指针,可是没有tracking这个分支的本地分支:

    * master
      remotes/origin/master
      remotes/origin/source

    相同我们能够在.git/refs/remotes/origin下看到分支的名字,可是refs/heads以下并没有。我们来检出这个远程分支:

    git checkout -b source origin/source

    这时候git branch -a 显示就跟git1一致了。git2下也能够编辑source分支并同步。这些都是比較常见的操作,我们须要注意的是。多分支下默认的參数。比方,在两个分支都改动一点东西:

    cd ../git1
    git checkout master
    //modify 
    git add .
    git commit -m "master modify"
    git checkout source
    //modify
    git add .
    git commit -m "source modify"

    这时候git push origin 是针对当前分支的,所以两个分支同一时候push更新仅仅能

    git push origin
    git checkout master
    git push origin

    pull更新的时候

    cd ../git2
    git checkout master
    git pull origin

    这会同一时候更新两个分支的指针。可是不会merge还有一个分支,我们去还有一个分支下

    git checkout source
    git pull origin

    可是出错例如以下:

    You asked to pull from the remote 'origin', but did not specify
    a branch. Because this is not the default configured remote
    for your current branch, you must specify a branch on the command line.

    问题在于没有给当前分支配置merge的路径,git不知道去merge哪个分支。(尽管我认为既然是tracking的不应该不知道啊)。

    假设你有 1.6.2 以上版本号的 Git。—track 选项能够同一时候配置merge的路径:

    git checkout --track origin/serverfix

    这里我们改动配置文件增加branch “source”:

    [core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
    [remote "origin"]
        url = /media/cxh/backup/work/ceshi/git/server
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master"这里指server上的refs/heads/master
    [branch "source"]
        remote = origin
        merge = refs/heads/source

    这意味着每次fetch origin的时候更新全部remotes/origin的头指针到refs/heads/以下,详细能够去.git下查阅这个文件夹,可是头指针都是仅仅读的。

    merge是由所在branch定义的。

    我们加了branch “source”的配置指定当前source的merge策略是使用server端的refs/heads/source来合并到当前分支。

    这样就能够顺利的git pull origin了。

    推送远程分支到不同server

    我们先建立新的repo:

    cd ..
    mkdir server2
    cd server2
    git init --bare

    增加git1副本,并提交

    git remote add server xxx/server2
    git push server

    上面过程的本质是提交当前分支头指针到server。相当于拷贝refs/head/xxx到refs/remotes/server/下并提交。

    git push server会被展开成

    git push server 当前分支名:当前分支名

    我们能够在git2副本相同增加该repository并更新引用

    git remote add server xxx/server2
    git fetch server

    能够看到refs下文件夹结构例如以下:

    ├── heads
       ├── master
       └── source
    ├── remotes
       ├── origin
          ├── master
          └── source
       └── server
           └── source
    └── tags

    总结一下

    • update

      • fetch操作的本质是更新repo所指定远程分支的头指针(server->refs/remotes/xxx/)

      • merge操作的本质是合并当前分支和指定的头指针(refs/remotes/xxx->refs/heads)

      • pull操作的本质是fetch + merge

    • commit

      • commit的本质是改动了当前分支的头指针(refs/heads)

      • push操作本质是提交当前分支头指针到server,顺便也改动了本地存储的server头指针(refs/remotes/xxx)

    • checkout

      • 复制本地分支的本质是拷贝了refs/heads/下的一个头指针

      • push本地分支到server的本质是把这个头指针上传服务器,顺便拷贝了本地存储的server头指针(refs/remotes/xxx)

      • tracking远程分支的本质是把refs/remotes/下的指针复制到了refs/heads下

    注:以上过程都没有涉及数据流。

    參考文献:

    [1] Git 分支 – 远程分支, http://git-scm.com/book/zh/Git-%E5%88%86%E6%94%AF-%E8%BF%9C%E7%A8%8B%E5%88%86%E6%94%AF

    [2] The Configuration File – “Branch” Section, http://www.gitguys.com/topics/the-configuration-file-branch-section/


    本文版权归CXH_ME全部,原创不易,人艰不抄,转载还请注明出处。谢谢

  • 相关阅读:
    通知:逆天异常库 V1.0版本支持下载了~~
    【源码】Word转PDF V1.0.1 小软件,供新手参考
    GitHub实战系列汇总篇
    GitHub实战系列~4.把github里面的库克隆到指定目录+日常使用 2015-12-11
    GitHub实战系列~3.提交github的时候过滤某些文件 2015-12-10
    Windows无法安装到这个磁盘。请确保在计算机的BIOS菜单中启用了磁盘控制器
    GitHub实战系列~2.把本地项目提交到github中 2015-12-10
    Git异常:fatal: could not create work tree dir 'XXX': No such file or directory
    GitHub实战系列~1.环境部署+创建第一个文件 2015-12-9
    肉肉好走,愿你在异界依旧快乐活泼
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7290657.html
Copyright © 2011-2022 走看看