猴子都能看懂的《Git 分支管理》 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
git
Pro Git
Atlassian Git Tutorial
Pro Git 简体中文翻译
GitX
CodingNET
V2EX    git

猴子都能看懂的《Git 分支管理》

  •  3
     
  •   CodingNET 2016-01-27 16:57:24 +08:00 8230 次点击
    这是一个创建于 3611 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本章我们会介绍使 Git 与其它版本控制系统区别开来的最关键特点 Git 的分支。它被称为 Git 的“必杀技”。
    以及如何使用和管理分支。

    什么是分支

    分支一方面类似科幻电影里面经常出现的平行宇宙,每个分支的代码版本都是独立演进的,分支之间的代码版本完全不会干扰另外一个代码版本的开发。但是,与平行宇宙不同的一点是,分支之间还能合并。

    Git 的分支相比 SVN 要轻量很多,这是因为 Git 分支并不是复制一个新仓库,而是为一个分支存储一个指针,这个指针将指向某个提交对象。没错,这就和数据结构中常见的指针链表一样。所以 Git 的分支只是指针,并没有将仓库进行复制,每次提交都会让当前的分支向后移动,指向最后一次提交的对象。当你在切换分支时, Git 也只是改变指向当前所在分支的特殊指针 HEAD ,所以可以快速地在各个分支之间进行切换。

    分支的功能

    分支在实际中可以方便的隔离开发。
    假设你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

    创建一个分支

    在 Coding.net 上创建分支

    Coding.net 界面上可以进入到项目中,依次点击 [代码] -> [分支] -> [新建分支]:

    图片

    图片

    在命令行创建本地分支

    也可以在命令行用 git branch 新建一个分支,回到上一章中提到的 learn-git 项目,我们在本地运行以下命令:

    $ git branch learn-branch 

    这条命令将会在本地仓库创建一个名为 "learn-branch" 的分支,这条分支指向最近一次提交的数据。要注意的是,运行该命令后,当前工作分支仍然是在 "master" 分支上,需要使用 git checkout 命令来进行分支之间的切换。

    切换分支

    本地分支切换

    之前我们已经在本地创建好了分支,接下来切换到 "learn-branch" 分支:

    $ git checkout learn-branch Switched to branch 'learn-branch' 

    git checkout 下面这句话告诉我们,我们已经成功地将工作分支切换到了 "learn-branch" 分支。

    远端分支切换

    Coding.net 提供在线的分支切换,在项目代码页, master 标签下拉菜单处可以选择其他分支。

    图片

    也可以在分支页进行选择:

    图片

    合并分支

    接下来我们将描述本地两种常见情形下的合并分支操作。本地的分支合并都是在命令行解决的。

    快进式合并

    快进式合并分支,也叫 Fast Foreword 。 我们在 "learn-branch" 分支上进行一些操作,创建一个新的 txt 文件 "learn-branch.txt",接着在其中输入一行 "I am studying git branch":

    $touch learn-branch.txt $echo I am studying git branch > learn-branch.txt 

    接下来我们将 "learn-branch.txt" 加入到跟踪文件,并提交到本地仓库:

    $git add learn-branch.txt $git commit -m "add learn-branch.txt" [learn-branch fce6c4e] add learn-branch.txt 1 files changed, 1 insertions(+) create mode 100644 learn-branch.txt 

    接下来我们回到 "master" 分支,并将 "learn-branch" 分支合并进来:

    $ git checkout master Switched to branch 'master' Your branch is up-to-date with 'origin/master'. $ git merge learn-branch Updating ca62ea0..fce6c4e Fast-forward learn-branch.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 learn-branch.txt 

    git merge [分支名] 命令将指定分支合并到当前工作分支中。请注意,合并时出现了 "Fast forward" 的提示。由于当前 "master" 分支所在的提交对象是要并入的 learn-branch 分支的直接上游, Git 只需把 master 分支指针直接右移。换句话说,如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进( Fast forward )。

    合并之后,"master" 分支和 "learn-branch" 分支实际上是指向同一个位置。此时你可以通过

    $git branch -d [分支名] 

    来删除某个分支。

    普通分支合并

    分支合并之前,最好使用 git pull 将 "master" 分支的代码更新到最新:

    如果我们在合并之前对 "master" 分支和 "learn-branch" 分支都做了一些修改,那合并时就不会像快进合并那么简单了。

    我们首先在 "master" 分支中做一些修改,比如将 "lear-branch.txt" 的内容进行修改:

    $echo I am on master branch > lear-branch.txt $git commit -m "alpha" [master a72cad8] alpha 1 files changed, 1 insertions(+), 1 deletion(-) 

    接下来,我们进入到 "learn-branch" 分支,也对 "learn-branch.txt" 进行一些修改:

    $git checkout learn-branch Swtiched to branch 'learn-branch' $echo I am on learn-branch branch > lear-branch.txt $git commit -m "beta" [learn-branch 27a4a6e] beta 1 files changed, 1 insertions(+), 1 deletion(-) 

    我们回到 "master" 分支再尝试合并分支:

    $git checkout master Swtiched to branch 'master' $git merge learn-branch Auto-merging learn-branch.txt CONFLICT (content): Merge conflict in learn-branch.txt Automatic merge failed; fix conflicts and then commit the result. 

    通常来说,当工作分支所指向的提交对象并不是需合并分支的直接祖先, Git 不得不进行一些额外处理。 Git 会根据分支的内容自动创建了一个包含了合并结果的提交对象,这个新的提交对象会包涵两次提交的内容。但是我们在两个分支中操作了同一个文件的同一个部分,这就需要我们手动来解决冲突了。

    现在运行 git status 命令,我们会看到在哪里出现了冲突:

    $ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add <file>..." to mark resolution) both modified: learn-branch.txt no changes added to commit (use "git add" and/or "git commit -a") 

    现在我们打开 learn-branch.txt ,会发现 Git 加入了冲突解决标记:

    <<<<<<< HEAD I am on master branch ======= I am on learn-branch branch >>>>>>> learn-branch 

    可以看到 ======= 隔开的上半部分,是 HEAD (即 master 分支,在运行 merge 命令时的工作分支)中的内容,下半部分是在 learn-branch 分支中的内容。解决冲突的办法无非是二者选其一或者人工亲自整合到一起。把上述内容修改为这样:

    I am on master branch 

    接下来运行 git add 来告诉 Git 冲突已经解决,并运行 git commit 来完成合并:

    $git add learn-branch.txt $git commit -m "conflict resolved" [master cadd265] conflict resloved 

    这样的合并冲突在快进合并中不可能发生。

    分支推送到仓库

    当你想和其他人分享某个本地分支时,你需要把它推送到一个你拥有写权限的远程仓库。你创建的本地分支不会因为你的写入操作而被自动同步到你引入的远程服务器上,你需要明确地执行推送分支的操作。换句话说,对于无意分享的分支,你尽管保留为私人分支好了,而只推送那些协同工作要用到的特性分支。

    我们可以使用 git push [仓库名] [分支名] 将之前在本地创建的 "learn-branch" 分支推送到 部署在 Coding.net 的 "learn-git" 项目中:

    $ git push origin serverfix Counting objects: 7, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 333 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To https:git.coding.net/Kyle_lyk/learn-git.git * [new branch] learn-branch -> learn-branch 

    现在查看 "learn-git" 仓库,你就会发现除了 "master" 分支外,还增加了一个 "learn-branch" 分支。

    合并请求

    Coding 推荐使用合并请求,在线将 2 个分支合并。合并请求分为

    - MergeRequest 针对私有项目 - PullRequest 针对公开项目 

    私有项目

    图片

    当你将分支推送到远端仓库后,通过新建&提交“合并请求”

    图片

    在创建新的合并请求时,可以填写代码评审,并引用项目内任务进行关联。 合并请求(MR) 发起人可以在该 MR 被合并前,随时对代码评审和引用任务进行编辑。点击提交,即可以创建一个合并请求( MR ) ,系统会自动判断出该 MR 的是否可以合并状态。

    图片

    在 MR 页面里面, MR 的提交者可以取消 MR , MR 目标分支的管理者(对该分支有写权限的项目成员),可以选择合并或者拒绝。 MR 支持 Markdown 语法评论。

    # 标志引用资源

    每个任务,讨论, MR 也有一个独特的引用 ID , 并通过 #ID 被引用到项目内其它地方。
    项目内支持 Markdown 编辑器的地方都支持“#”自动提示(任务描述、讨论、合并请求描述等),并引用相应资源。

    • 讨论

    图片

    • Merge Request

    图片

    公开项目

    图片

    通过 Fork - Pull Request 的方式,提交合并请求。

    首先,你需要将共有项目 fork 到你自己的仓库,如图。

    图片

    fork 后会在你的项目空间生成一个对应的项目,然后修改 fork 后项目的代码。

    图片

    当准备同源项目合并时,创建合并请求( Pull Request )

    图片

    点击提交,即可以创建一个合并请求( PR ) ,系统会自动判断出该 PR 的是否可以合并状态。

    代码行级比对

    代码行级比对( Line Notes ) 是 Coding 开发的可以针对代码的 diff 进行行级别的评论功能,支持 Markdown 语法,可以方便的用来进行 Code Review 。
    你可以在代码 commit 页面,和合并请求( MR /PR ) 页面使用该功能。如下图:

    此处放上之前 Line Notes 上线推广时录制的 Gif 。

    保护分支

    保护分支是 Coding 针对 Git 中有关代码权限开发的一个功能,阅读之前,我假设您已经知道分支的基本概念和用法。简而言之,保护分支就是将特定的分支保护起来,以防止被破坏。

    在项目代码分支页面,我们可以设置保护分支,如下图所示:

    图片

    分支名称左边有一个 lock 标志,表示改分支是保护分支。我们可以点击右侧的绿色盾牌标志来设置开关保护分支和设置保护分支成员。如下图:

    图片
    勾选某个项目成员,即代表改成员对该分支有 write 权限(可以 push 至该分支,可以接受该分支的 MR )。

    其他成员,则没有权限 push 至该分支,当 push 至该分支的时候,会得到如下错误提示:

    图片
    所以,当你看到这个错误提示的时候,就知道是因为没有该保护分支权限而导致 push 失败了。

    查看原文及更多: https://coding.net/help/doc/git/git-branch.html

    25 条回复    2016-02-19 12:40:18 +08:00
    techmoe
        1
    techmoe  
       2016-01-27 17:45:33 +08:00 via Android   1
    竟然是 coding 。。
    DeutschXP
        2
    DeutschXP  
       2016-01-27 17:45:49 +08:00 via iPhone
    此处放上之前 Line Notes 上线推广时录制的 Gif 。
    wenbinwu
        3
    wenbinwu  
       2016-01-27 17:48:39 +08:00
    不是猴子,看不懂。。。
    lj61785636
        4
    lj61785636  
       2016-01-27 17:51:22 +08:00   1
    正在用 coding ,感觉不错
    Flygoat
        5
    Flygoat  
       2016-01-27 18:07:34 +08:00 via iPhone   1
    没错,你就是只猴子。
    joye1230
        6
    joye1230  
       2016-01-27 18:11:21 +08:00   1
    虽然是软文还觉得要点赞
    Khlieb
        7
    Khlieb  
       2016-01-27 18:30:28 +08:00 via Android
    @techmoe 抠腚
    loveuqian
        8
    loveuqian  
       2016-01-27 18:32:53 +08:00 via iPhone
    git 服务商能不能出一本完整的 git 教学啊
    贵司的程序员应该都精通 git 吧
    qihboy
        9
    qihboy  
       2016-01-27 18:37:17 +08:00   1
    一直在用 coding,做得确实非常不错

    如果能把 coding 和 tower 合并到一起,就强大得宇宙无敌了
    CodingNET
        10
    CodingNET  
    OP
       2016-01-27 18:40:11 +08:00
    @loveuqian
    推荐您阅读我司程序员参与翻译校审的《 Pro Git 第二版》 http://git-scm.com/book/zh/v2
    Flygoat
        11
    Flygoat  
       2016-01-27 18:40:46 +08:00 via iPhone   1
    话说 coding 可以看看 Buddy.Works 加上自动部署就好了。
    CodinNET
        12
    CodingNET  
    OP
       2016-01-27 18:44:02 +08:00
    @Flygoat
    感谢您的建议,我们会考虑的。
    laocp
        13
    laocp  
       2016-01-27 22:03:52 +08:00   2
    《猴子都能懂的 GIT 入门》,这个是交互版的:
    http://backlogtool.com/git-guide/tw/
    ablula
        14
    ablula  
       2016-01-27 23:25:31 +08:00
    实战项目里还需要约定好一个 git workflow ;
    推荐 gitflow: http://blog.sweetvvck.com/2015/12/16/原-Gitflow 实践 /
    ablula
        15
    ablula  
       2016-01-27 23:33:47 +08:00
    oska874
        16
    oska874  
       2016-01-27 23:58:57 +08:00
    我不如猴子啊。
    expkzb
        17
    expkzb  
       2016-01-28 09:48:53 +08:00
    汪汪汪
    miclushine
        18
    miclushine  
       2016-01-28 10:22:10 +08:00   1
    虽然是软文,但是图文并茂的教程确实不错。
    ghostsf
        19
    ghostsf  
       2016-01-28 13:11:42 +08:00   1
    写得好详细 mark 支持 coding
    Action530
        20
    Action530  
       2016-01-28 13:20:54 +08:00   1
    关键是软得好看啊哈哈。 Coding 还是很不错的,自己的小项目在上面。一直想安利领导用上
    googlefans
        21
    googlefans  
       2016-01-28 20:17:24 +08:00
    太长了。。
    qloog
        22
    qloog  
       2016-01-29 08:41:16 +08:00   1
    git 讲解清晰易懂。

    coding 使用说明也是常用的。
    yuchting
        23
    yuchting  
       2016-01-29 10:18:14 +08:00   1
    再看五年,你若安在,我等再用。
    anym0us
        24
    anym0us  
       2016-01-29 11:26:30 +08:00   1
    很详细,清晰,易懂
    Frapples
        25
    Frapples  
       2016-02-19 12:40:17 +08:00   1
    原来这个系列的教程是你们写的。。。我就说嘛那个猴子怎么那么眼熟
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3222 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 04:54 PVG 12:54 LAX 20:54 JFK 23:54
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86