zoukankan      html  css  js  c++  java
  • Git(二)

    三、分支管理

    1.创建和合并分支

    ①图解

    ​ 每次提交,Git都会把它们串成一条时间线。这条时间线就是一个分支。截至到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向mastermaster才是指向提交的,所以HEAD指向的就是当前分支。

    ​ 一开始的时候,master分支是一条线,Gitmaster指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

    Git分支(一)

    ​ 每次提交,master分支都会向前移动一步,这样随着你不断提交,master分支的线也越来越长。

    ​ 当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,然后HEAD指向dev,就表示当前分支在dev上:

    Git分支(二)

    ​ 你看,Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

    Git分支(三)

    ​ 假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

    Git分支(四)

    ​ 所以Git合并分支也很快!就改改指针,工作区内容也不变合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

    Git分支(五)

    ②命令

    ​ 首先,我们创建dev分支,然后切换到dev分支:

    $ git checkout -b dev
    Switched to a new branch 'dev'
    

    git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

    $ git branch dev
    $ git checkout dev
    Switched to branch 'dev'
    

    ​ 然后,用git branch命令查看当前分支:

    $ git branch
    * dev
      master
    

    git branch命令会列出所有分支,当前分支前面会标一个*号。

    ​ 在dev分支修改、添加、提交readme.md,切换回mastergit checkout master)分支后,再查看readme.md文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master分支此刻的提交点并没有变:

    Git分支(六)

    ​ 现在,我们把dev分支的工作成果合并到master分支上:

    $ git merge dev
    Updating d46f35e..b17d20e
    Fast-forward
     readme.md | 1 +
     1 file changed, 1 insertion(+)
    

    git merge命令用于合并指定分支到当前分支,通过上面的Fast-forward信息,Git告诉我们这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。当然,也不是每次合并都能Fast-forward,我们后面会讲其他方式的合并。合并完成后,就可以放心地删除dev分支(git branch -d dev)。

    ​ 因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

    ③switch

    我们注意到切换分支使用git checkout <branch>,而前面讲过的撤销修改则是git checkout -- <file>,同一个命令,有两种作用,确实有点令人迷惑,因此,最新版本的Git提供了新的git switch命令来切换分支。

    ​ 创建并切换到新的dev分支:git switch -c dev

    ​ 切换到master分支:git switch master

    2.解决冲突

    ​ 当master分支和dev分支各自都分别有新的提交,变成了这样:
    Git冲突

    ​ 这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,我们试试看:

    $ git merge dev
    Auto-merging readme.md
    CONFLICT (content): Merge conflict in readme.md
    Automatic merge failed; fix conflicts and then commit the result.
    

    ​ 通过git status可以告诉我们冲突的文件是哪个,然后查看readme.md:

    Git is a distributed version control system.
    <<<<<<< HEAD
    Creating a new branch is quick & simple.
    =======
    Creating a new branch is quick AND simple.
    >>>>>>> feature1
    

    Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,我们修改如下后保存:

    Creating a new branch is quick and simple.
    

    ​ 其实这就是一个解决冲突的过程,然后提交修改。现在,master分支和feature1分支变成了下图所示:

    Git解决冲突

    ​ 最后,删除dev分支(git branch -d dev

    3.分支管理策略

    ​ 合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。操作命令为git merge --no-ff -m "merge with no-ff" dev

    ​ 通过git log --graph --pretty=oneline --abbrev-commit以看到分支合并图。

    在实际开发中,我们应该按照几个基本原则进行分支管理:

    ​ 首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。所以,团队合作的分支看起来就像这样:

    分支管理策略

    4.Bug分支

    ​ 当工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?

    Git提供了一个stash功能,可以把当前工作现场“储藏”起来,命令为git stash,使用完该命令后用git status查看工作区是干净的。首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支issue-100:git checkout -b issue-100,修改完毕后,切换到master分支,并完成合并,最后删除issue-100分支。

    ​ 然后我们切换到刚才工作的分支dev,使用git stash pop恢复刚才工作的内容,同时我们需要将issue-100修复的bug同步到dev分支,使用git cherry-pick <commitId>,这样就完成了devbug的修复,同时还还原了之前的正在进行的工作。

    5.多人协作

    当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。要查看远程库的信息,用git remote

    $ git remote
    origin
    

    ​ 或者,用git remote -v显示更详细的信息

    $ git remote -v
    origin  https://github.com/hucheng1997/learngti.git (fetch)
    origin  https://github.com/hucheng1997/learngti.git (push)
    

    ​ 上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。

    推送master或其他分支到远程库:git push origin master/dev,实际开发中一般需要将masterdev分支推送到远程库。

    抓取分支:git pull origin master/dev

    创建远程origindev分支到本地git checkout -b dev origin/dev

    ​ 如果是直接创建的dev,在git pull的时候会失败,此时需要执行命令git branch --set-upstream-to=origin/dev dev

    多人协作的工作模式通常是这样

    1. 首先,可以试图用git push origin <branch-name>推送自己的修改;
    2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
    3. 如果合并有冲突,则解决冲突,并在本地提交;
    4. 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!

    ​ 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>

    四、标签管理

    ​ 发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。

    1.创建标签

    • git tag <tagname> [commitId]:用于新建一个标签,默认为HEAD,也可以指定一个commit id;

      注:简洁查看历史记录git log --pretty=oneline --abbrev-commit

    • git tag -a <tagname> -m "blablabla...":可以指定标签信息;

    • git tag:可以查看所有标签。

    • git show <tagname>:可以查看所有标签

    2.操作标签

    • 删除taggit tag -d v0.1

    • 推送某个标签到远程:git push origin v1.0

    • 一次性推送全部尚未推送到远程的本地标签:git push origin --tags

    • 删除远程标签

      ​ 先删除本地的git tag -d v0.9,然后删除远程:git push origin :refs/tags/v0.9

  • 相关阅读:
    [DB] 数据库的连接
    JS leetcode 翻转字符串里的单词 题解分析
    JS leetcode 拥有最多糖果的孩子 题解分析,六一快乐。
    JS leetcode 搜索插入位置 题解分析
    JS leetcode 杨辉三角Ⅱ 题解分析
    JS leetcode 寻找数组的中心索引 题解分析
    JS leetcode 移除元素 题解分析
    JS leetcode 最大连续1的个数 题解分析
    JS leetcode 两数之和 II
    JS leetcode 反转字符串 题解分析
  • 原文地址:https://www.cnblogs.com/hucheng1997/p/11799145.html
Copyright © 2011-2022 走看看