美文网首页
git-03-分支

git-03-分支

作者: hylexus | 来源:发表于2017-03-02 20:55 被阅读9次

    [TOC]

    说明

    本篇文章是本人回顾git知识点时从《progit》一书中摘抄出来的笔记,毕竟好记性不如烂笔头嘛,不然我也不会回顾了……
    另请大神绕路,不喜勿喷……

    1 基础知识

    初始提交

    $ git init repo-1
    Initialized empty Git repository in H:/tmp/git-test/repo-1/.git/
    
    $ cd repo-1/
    
    # 建立三个测试文件
    $ touch readme.md config.xml db.properties
    
    # 加入暂存区 待下次提交
    $ git add readme.md config.xml db.properties
    
    # 提交
    $ git commit -m 'init project'
    

    此时的git仓库中的对象可能大致如下图所示:

    blob

    说明:

    • blob对象:保存着文件快照
    • tree对象:记录着目录结构和blob对象索引
    • commit对象:包含着指向前述树对象的指针和所有提交信息

    做些修改再提交

    # 修改readme.md
    $ echo "haha" >> readme.md
    $ git add .
    $ git commit -m "second commit"
    
    # 修改db.properties
    $ echo "db.user=root" >> db.properties
    $ git add .
    $ git commit -m "db.properties modified"
    
    
    # 看看此时的提交历史
    $ git log --oneline --decorate --all
    7240135 (HEAD -> master) db.properties modified
    828bc57 second commit
    e314b67 init project
    

    此时的仓库中快照可能是下面这个样子:

    snapshort

    就像前面说的,git不存储文件差异,每次提交都是记录一次文件的快照,担任文件内容不变的时候不会重复存储快照了。

    每个commit一般都有其父commit对象(除了第一个commit对象)。

    git的分支本质也就是指向某个特定commit对象的指针。

    这样的话,在分支切换、分支建立的时候,都是非常迅速的。

    当你首次提交之后,git会建立一个名为master的默认分支。即使你不显示地主动创建分支,你也是在master分支上工作的。每次提交后,都是指向最后一个commit对象。也就是说,在commit的时候这个指针是自动移动的。

    在你创建新分支的时候,其实是创建了一个新的指针。

    2 分支基本操作

    2.1 新建分支

    # 建立名为b1的分支
    $ git branch b1
    

    此时的分支信息如下所示:

    新建分支
    • 此时的master和b1分支都指向最新的一个commit对象
    • 上图中的HEAD指的是一个记录当前所处本地分支的指针。也就是说HEAD是当前分支的别名
    • 在你使用git branch b1建立分支后,并没有自动切换到新分支b1上去
    # 此时的b1和master都是指向特征码为7240135的commit对象
    # HEAD -> master表明,当前所处分支任然是master分支
    $ git log --oneline --decorate
    7240135 (HEAD -> master, b1) db.properties modified
    828bc57 second commit
    e314b67 init project
    

    2.2 切换分支

    $ git checkout b1
    Switched to branch 'b1'
    
    
    # HEAD -> b1 表明,当前所处分支是b1
    $ git log --oneline --decorate
    7240135 (HEAD -> b1, master) db.properties modified
    828bc57 second commit
    e314b67 init project
    

    HEAD -> b1 表明,当前所处分支是b1。那么此时的分支图示应该像下面这样:

    branch-b1

    2.3 新分支上做修改

    # 在分支b1上修改文件readme.md
    $ echo "new line @ brach b1" >> readme.md
    
    $ git add readme.md
    $ git commit -m "modified on b1 - 1"
    

    查看此时的提交历史

    $ git log --oneline --decorate
    cf385f4 (HEAD -> b1) modified on b1 - 1
    7240135 (master) db.properties modified
    828bc57 second commit
    e314b67 init project
    

    可以得出:

    • 最新的一次commit对象是在分支b1上做的
    • 当下处于b1分支

    那么此时的分支示例图大概如下:

    新分支上修改文件

    2.4 分支合并

    回到master分支

    $ git checkout master
    Switched to branch 'master'
    
    $ git log --decorate --oneline
    7240135 (HEAD -> master) db.properties modified
    828bc57 second commit
    e314b67 init project
    

    在master分支上修改db.properties

    $ cat db.properties
    db.user=root
    
    # 在master分支上修改db.properties
    $ echo "db.password=123" >> db.properties
    
    $ git add db.properties
    $ git commit -m "db.properties modified on master"
    
    

    此时的分支示例图

    $ git log --decorate --oneline --graph
    * 957a3d0 (HEAD -> master) db.properties modified on master
    * 7240135 db.properties modified
    * 828bc57 second commit
    * e314b67 init project
    
    分支分叉
    • 此时分支已经有了分叉
    • 可以在需要的时候合并

    合并b1分支到master

    $ git merge b1
    Merge made by the 'recursive' strategy.
     readme.md | 1 +
     1 file changed, 1 insertion(+)
    

    查看分支历史

    $ git log --decorate --oneline --graph
    *   3115451 (HEAD -> master) Merge branch 'b1'
    |\
    | * cf385f4 (b1) modified on b1 - 1
    * | 957a3d0 db.properties modified on master
    |/
    * 7240135 db.properties modified
    * 828bc57 second commit
    * e314b67 init project
    
    分支合并

    3 分支管理

    列出所有分支

    $ git branch
      b1
    * master
    

    删除分支

    git branch -d <branch-name>
    

    master分支前面的星号表示当前HEAD指向master,也就是说当前处于master分支。

    查看每一个分支的最后一次提交

    $ git branch -v
      b1     cf385f4 modified on b1 - 1
    * master 3115451 Merge branch 'b1'
    

    查看已经合并到/尚未合并到当前分支的分支

    # b1分支已经合并到当前分支
    $ git branch --merged
      b1
    * master
    
    # 尚未合并到当前分支的分支
    $ git branch --no-merged
    

    此处使用 git branch --merged 列出的这个列表中分支名字前没有星号的分支通常可以使用 git branch -d 删除掉。因为在这些分支上所作的修改已经被合并到其他分支了。

    4 远程仓库与远程分支

    4.1 远程仓库

    远程仓库是指托管在因特网或其他网络中的项目的版本库。可以有若干个远程仓库。

    $ git clone https://github.com/java-template/jt-808-protocol.git
    
    $ cd jt-808-protocol/
    
    # 列出指定的每一个远程服务器的简写
    (master) $ git remote
    origin
    
    (master) $ git ls-remote
    From https://github.com/java-template/jt-808-protocol.git
    7c86e1cde856183e794b31ac72f2b02377b6f4b8    HEAD
    7c86e1cde856183e794b31ac72f2b02377b6f4b8    refs/heads/master
    
    
    # 选项 -v,显示简写与其对应的 URL
    (master) $ git remote -v
    origin  https://github.com/java-template/jt-808-protocol.git (fetch)
    origin  https://github.com/java-template/jt-808-protocol.git (push)
    
    

    4.2 远程仓库管理

    新增远程仓库

    git remote add <name> <url>
    
    # 添加简写名为another的远程仓库
    (master) $ git remote add another https://github.com/java-template/jt-808-protocol.git
    
    # 列出所有的远程仓库
    (master) $ git remote -v
    another https://github.com/java-template/jt-808-protocol.git (fetch)
    another https://github.com/java-template/jt-808-protocol.git (push)
    origin  https://github.com/java-template/jt-808-protocol.git (fetch)
    origin  https://github.com/java-template/jt-808-protocol.git (push)
    
    # 此时可以使用another来代替整个URL来使用
    (master) $ git pull another 
    From https://github.com/java-template/jt-808-protocol
     * [new branch]      master     -> another/master
    You asked to pull from the remote 'another', 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.
    

    注意

    • 如果你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 origin 为简写

    重命名远程仓库

    # 将远程服务器another重命名为other
    (master) $ git remote rename another other
    (master) $ git remote -v
    origin  https://github.com/java-template/jt-808-protocol.git (fetch)
    origin  https://github.com/java-template/jt-808-protocol.git (push)
    other   https://github.com/java-template/jt-808-protocol.git (fetch)
    other   https://github.com/java-template/jt-808-protocol.git (push)
    

    删除远程仓库

    # 删除远程服务器other
    (master) $ git remote rm other 
    (master) $ git remote -v
    origin  https://github.com/java-template/jt-808-protocol.git (fetch)
    origin  https://github.com/java-template/jt-808-protocol.git (push)
    

    4.3 从远程仓库获取数据

    git fetch [remote-name]
    
    • 此命令会访问远程仓库,从中拉取所有你还没有的数据
    • 执行完成后,你将会拥有那个远程仓库中所有分支的引用
    • 但是此命令并不会自动merge,也就是说需要你手动合并
    git pull
    
    • 该命令可以认为是git fetchgit merge的组合
    • 当然,自动合并出错还得你自己解决冲突了

    4.4 推送数据到远程分支

    远程分支以 (remote)/(branch) 形式命名,或称之为唯一标识它。
    比如origin/master表示远程服务器orgin上的master分支,origin/iss256表示origin服务器上的一个名为iss256的分支。

    git push [remote-name] [branchname]
    

    将 master 分支推送到 origin 服务器

    $ git push origin master
    

    4.5 一点说明

    当clone一个远程仓库时,会自动建立一个master分支来跟踪origin/master分支

    • origin是默认的远程服务器的名称
    • master是默认的分支名
    • 当然,origin和master除了是默认的名称外,没有其他任何特别之处

    至于跟踪分支的细节,请看下文

    5 跟踪分支

    跟踪分支是与远程分支有直接关系的本地分支。

    也就是说:在一个跟踪分支上执行 git pull,Git 能自动地识别去哪个服务器上抓取、也知道将fetch到的数据合并到哪个分支。

    5.1 创建跟踪分支

    • 当clone一个远程仓库时,会自动建立一个master分支来跟踪origin/master分支
    • 使用git checkout -b [branch] [remotename]/[branch]创建跟踪分支
    • 或者可以在checkout的时候使用--track选项
    # 创建一个名为another-track-branch的分支作为origin/master的跟踪分支
    (master) $ git checkout -b another-track-branch origin/master Branch another-track-branch set up to track remote branch master from origin.
    Switched to a new branch 'another-track-branch'
    (another-track-branch) $ 
    

    5.2 修改跟踪分支

    可以使用 -u--set-upstream-to 选项运行 git branch 来显式地设置跟踪的远程分支

    # 设置当前分支跟踪origin服务器的master分支
    (another-track-branch) $ git branch --set-upstream-to origin/master 
    

    5.3 查看跟踪分支

    (another-track-branch) $ git branch -vv
    * another-track-branch 7c86e1c [origin/master] 调试工具
      master               7c86e1c [origin/master] 调试工具
      test1                7c86e1c 调试工具
    (another-track-branch) $ git branch -vv
    

    可以看出,此处:

    • another-track-branch分支和master分支都在跟踪origin/master分支
    • another-track-branch前面的星号表示目前处于another-track-branch分支
    • test1分支没有跟踪任何分支

    参考资料

    • 《progit》

    相关文章

      网友评论

          本文标题:git-03-分支

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