第四个模块 Git及分支使用场景

作者: 霄峰 | 来源:发表于2016-09-21 13:33 被阅读515次

    吕 倡 博客
    吕倡-搭建 GitLab 服务器
    吕倡-(项目管理 进阶篇)Git 团队版本管理 原则与思路
    Git教程
    国内git平台 http://git.oschina.net/
    第四个模块-GIT远程分支回滚
    第四个模块-GIT多人开发合并远程分支代码

    git使用手册

    1. 安装git(Ubuntu)

    sudo apt-get install git
    
    //全局设置
    git config --global user.name "469306621" //这里写你的帐号
    git config --global user.email "469306621@qq.com" //这里写你的邮箱地址
    

    2. 基本命令

    创建仓库

    mkdir githome
    cd githome
    git init
    

    添加到暂存区

    git add .
    

    把暂存区的文件提交到版本库

    git commit -m '描述信息'
    

    查看git状态信息

    git status
    

    查看git日志信息

    git log //查看所有日志
    git reflog //查看所有的版本号
    git log --pretty=oneline //将信息显示到一行
    git log --graph //查看分支合并图
    git log --graph --pretty=oneline //以简要信息显示分支合并图
    

    创建|修改文件

    touch readme.md
    echo 'hello' >> readme.md
    说明:每次创建|修改都要
    git add .
    git commint -m '描述'
    

    丢弃工作区的修改

    git checkout -- 文件
    

    命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
    一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
    一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
    总之,就是让这个文件回到最近一次git commit或git add时的状态。

    删除(版本库删除)

    git rm readme.md
    git commint -m '删除信息'
    

    删除(本地删除)-另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:

    rm readme.md
    git checkout -- readme.md //从版本库中恢复
    

    取消删除(版本库删除)

    git rm readme.md
    git reflog
    git reset --hard 删除前的版本号 //恢复删除文件
    

    回滚

    git reset --hard HEAD^ //回滚到上一版本
    git reset --hard 版本号 //回滚到指定版本
    

    3. 远程仓库

    添加远程库

    mkdir gittest
    cd gittest
    git init
    touch README.md
    git add README.md
    git commit -m "first commit"
    git remote add origin git@git.oschina.net:469306621/gittest.git
    git push -u origin master
    

    从远程版本库克隆

    git clone git@git.oschina.net:469306621/gittest.git
    说明:git@git.oschina.net:469306621/gittest.git 是我的git地址,这里要替换成你的
    

    推送到远程

    git push origin dev:dev
    说明:dev:dev 第一个dev是当前本地分支,第二个dev是远程分支
    

    从远程版本库更新(拉取)

    git pull
    

    4. 分支

    1.创建dev分支,然后切换到dev分支

    git checkout -b dev
    //等于
    git branch dev
    git checkout dev
    

    查看当前分支

    git branch
    说明:列出所有分支,当前分支前面会标一个*号
    

    然后在当前的分支添加文件并提交

    touch test.txt
    echo 'OK' >> test.txt
    git add .
    git commit -m 'add a test'
    

    切换分支到master,合并分支

    //切换分支
    git checkout master
    
    //合并分支
    //方式一
    git merge dev
    说明:把dev分支合并到master
    通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息
    
    如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
    //方式二
    git merge --no-ff -m "merge with no-ff" dev
    注意:--no-ff参数,表示禁用Fast forward
    

    2.合并分支冲突(如果上一步合并分支出现冲突,冲突就会写入文件中)

    vim 冲突文件 //Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容
    
    //完成后
    git add . //添加到暂存区
    git commit -m '解决冲突' //提交
    

    Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容

    显示分支合并图

    git log --graph --pretty=oneline //以简要信息显示分支合并图
    

    删除分支

    git branch -d dev
    

    3.分支策略

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

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


      分支策略
    4. 合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并

    4.Bug分支

    软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

    当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。

    当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,当前正在dev上进行的工作还没有提交:

    git status
    ------------------------------------
    # On branch dev
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       new file:   hello.py
    #
    # Changes not staged for commit:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       modified:   readme.txt
    #
    

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

    Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

    git stash
    

    现在,用git status查看工作区,就是干净的,因此可以放心地创建分支来修复bug。

    首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支:

    git checkout master
    git checkout -b issue-101
    

    现在修复bug,需要把“Git is free software ...”改为“Git is a free software ...”,然后提交:

    git add .
    git commit -m '修复完成'
    

    修复完成后,切换到master分支,并完成合并,最后删除issue-101分支:

    git checkout master
    git merge --no-ff -m '修复完成-合并' issue-101
    git branch -d issue-101
    

    太棒了,原计划两个小时的bug修复只花了5分钟!现在,是时候接着回到dev分支干活了!

    git checkout dev
    git status
    

    工作区是干净的,刚才的工作现场存到哪去了?用git stash list命令看看

    git stash list
    

    工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法

    一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
    另一种方式是用git stash pop,恢复的同时把stash内容也删了

    git stash pop
    

    你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令

    git stash apply stash@{0}
    

    5.Feature分支

    软件开发中,总有无穷无尽的新的功能要不断添加进来。

    添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。

    如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。
    现在,你终于接到了一个新任务:开发代号为Vulcan的新功能,该功能计划用于下一代星际飞船。
    于是准备开发:

    git checkout -b feature-vulcan
    

    5分钟后,开发完毕:

    git add vulcan.php
    git commit -m 'add vulcan Function'
    

    切回dev,准备合并

    git checkout dev
    

    一切顺利的话,feature分支和bug分支是类似的,合并,然后删除。
    但是,
    就在此时,接到上级命令,因经费不足,新功能必须取消!
    虽然白干了,但是这个分支还是必须就地销毁:

    git branch -d feature-vulcan //警告:没有合并的分支不能删除
    git branch -D feature-vulcan //强行删除
    

    6.多人协作

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

    要查看远程库的信息,用git remote:

    git remote
    git remote -v //显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址
    

    推送分支
    推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上

    git push origin master //推送master分支
    
    //如果要推送其他分支,比如dev
    git push origin dev //推送dev分支
    

    但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?

    master分支是主分支,因此要时刻与远程同步;
    dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
    bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
    feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
    总之,就是在Git中,分支完全可以在本地自己藏着玩,是否推送,视你的心情而定!

    5. 标签

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

    命令git tag <name>用于新建一个标签,默认为HEAD,也可以指定一个commit id;
    git tag -a <tagname> -m "blablabla..."可以指定标签信息;
    git tag -s <tagname> -m "blablabla..."可以用PGP签名标签;
    命令git tag可以查看所有标签。

    在Git中打标签非常简单,首先,切换到需要打标签的分支上

    git branch
    

    然后,敲命令git tag <name>就可以打一个新标签

    git tag v1.0
    

    可以用命令git tag查看所有标签

    git tag
    

    默认标签是打在最新提交的commit上的
    有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?
    方法是找到历史提交的commit id,然后打上就可以了:

    git log --pretty=oneline --abbrev-commit
    ----------------------------------------
    6a5819e merged bug fix 101
    cc17032 fix bug 101
    7825a50 merge with no-ff
    6224937 add merge
    59bc1cb conflict fixed
    400b400 & simple
    75a857c AND simple
    fec145a branch test
    d17efd8 remove test.txt
    

    比方说要对add merge这次提交打标签,它对应的commit id是6224937,敲入命令

    git tag v0.9 6224937
    git tag -a v0.1 -m "version 0.9 released" 6224937 //带有说明的标签
    

    git show <tagname>查看标签信息

    git show v0.9
    

    如果标签打错了,也可以删除:

    git tag -d v0.9
    

    因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。

    如果要推送某个标签到远程,使用命令git push origin <tagname>

    git push origin v0.9
    

    或者,一次性推送全部尚未推送到远程的本地标签

    git push origin --tags
    

    命令git push origin <tagname>可以推送一个本地标签;
    命令git push origin --tags可以推送全部未推送过的本地标签;
    命令git tag -d <tagname>可以删除一个本地标签;
    命令git push origin :refs/tags/<tagname>可以删除一个远程标签。

    如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除

    git push origin -d v0.9
    

    然后,从远程删除

    git push origin :refs/tags/v0.9
    

    6. 忽略特殊文件

    在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件
    不需要从头写.gitignore文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore

    忽略文件的原则是:

    忽略操作系统自动生成的文件,比如缩略图等;
    忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
    忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。

    忽略某些文件时,需要编写.gitignore;
    .gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理!
    

    一个完整的.gitignore文件,内容如下

    # Windows:
    Thumbs.db
    ehthumbs.db
    Desktop.ini
    
    # Python:
    *.py[cod]
    *.so
    *.egg
    *.egg-info
    dist
    build
    
    # My configurations:
    db.ini
    deploy_key_rsa
    

    最后一步就是把.gitignore也提交到Git,就完成了

    可以用-f强制添加到Git

    git add -f .env
    

    可以用git check-ignore命令检查到底哪个规则写错了,

    git check-ignore -v .env
    

    7. 搭建Git服务器

    在远程仓库一节中,我们讲了远程仓库实际上和本地仓库没啥不同,纯粹为了7x24小时开机并交换大家的修改。

    GitHub就是一个免费托管开源代码的远程仓库。但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓库使用。

    搭建Git服务器需要准备一台运行Linux的机器,强烈推荐用Ubuntu或Debian,这样,通过几条简单的apt命令就可以完成安装。

    假设你已经有sudo权限的用户账号,下面,正式开始安装。

    第一步,安装git:

    sudo apt-get install git
    

    第二步,创建一个git用户,用来运行git服务:

    sudo adduser git
    

    第三步,创建证书登录:

    收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

    第四步,初始化Git仓库:

    先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:

    sudo git init --bare sample.git
    

    Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git:

    sudo chown -R git:git sample.git
    

    第五步,禁用shell登录:

    出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:

    git:x:1001:1001:,,,:/home/git:/bin/bash
    改为:
    git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
    

    第六步,克隆远程仓库:

    现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:

    $ git clone git@server:/srv/sample.git
    Cloning into 'sample'...
    warning: You appear to have cloned an empty repository.
    

    剩下的推送就简单了。


    项目中分支使用场景

    1. 分别在两台电脑上git clone 远程项目
    git clone git@git.oschina.net:469306621/githome.git
    cd githome
    git checkout -b dev
    
    1. 在第一台电脑上:
    //创建user-01分支
    git checkout -b user-01
    

    在第二台电脑上:

    //创建user-02分支
    git checkout -b user-02
    
    1. 假如要添加一个新的公共文件functions.php.
      user-01开发 获取日期功能;
      user-02开发 获取文件信息功能;
      在第一台电脑上:
    git branch  //查看是否在user-01分支上,如果不是切换到user-01分支上`git checkout user-01`
    touch functions.php
    

    然后向functions.php文件中添加内容,5分钟后功能写完了.提交到本地版本库

    git add .
    git commit -m 'add functions.php append getDate'
    

    之后合并到dev分支上

    git checkout dev
    git merge --no-ff -m 'add functions.php append getDate' user-01
    git pull origin dev //拉取远程dev分支,以防有冲突.如果有冲突,解决冲突后(`git add .` `git commit -m '信息'`);再次拉取直到没有冲突,然后提交!
    git push origin dev //提交到远程分支
    git log --pretty=oneline --graph //查看合并信息
    

    同时,第二电脑上操作与第一台电脑一样!

    相关文章

      网友评论

        本文标题:第四个模块 Git及分支使用场景

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