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

  • 相关阅读:
    直接拿来用 九个超实用的PHP代码片段(二)
    微信开发值得推荐的开源项目
    PHP文件下载原理
    简化PHP开发的10个工具
    CI Weekly #1 | 这份周刊,带你了解 CI/CD 、DevOps、自动化测试
    fir.im Weekly
    fir.im Weekly
    fir.im Weekly
    用 flow.ci 让 Hexo 持续部署
    fir.im Weekly
  • 原文地址:https://www.cnblogs.com/hucheng1997/p/11799145.html
Copyright © 2011-2022 走看看