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

吕 倡 博客
吕倡-搭建 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 //查看合并信息

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容