git

1 从服务器上克隆完整的Git仓库(包括代码和版本信息)到本机上。2 在自己的机器上根据不同的开发目的,创建分支,修改代码。3 在单机上自己创建的分支上提交代码、合并分支,提交到本地版本库。4 把服务器上最新版的代码pull/fetch下来,解决服务器版本库与本地代码的冲突,然后跟自己的主分支合并。5 如果没问题,push到服务器


如果中央服务器故障,Git本地仓库包含代码库还有历史库,不需要网络,自己可以在脱机环境查看开发的版本历史,在本地的环境开发也可以进行比对,回退等操作。Git都在本地保存了版本记录,所以大家合并起来就容易多了,等到服务器好了,直接提交就行了;或者可以随时创建一个新的中央库,随便从其他人那里复制一个然后同步就立刻恢复了中央库。

Git把数据看作是对小型文件系统的一组快照。

每次你提交更新,或保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。

为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。

Git概念理解

Git工作区域种类:

工作区(工作目录):电脑里能看到的目录

版本库( Git 仓库目录):工作区有一个隐藏目录.git,就是Git的版本库。

暂存区域:一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。

有时候也被  称作`索引',不过一  般说法还是叫暂存区域。


被管理文件的几种状态:

已修改(modified):表示修改了文件,但还没保存到本地版本库中

已暂存(staged):表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中

已提交(committed):表示数据已经安全的保存在本地版本库中

Git 工作流程:在工作目录中修改文件 à 暂存文件à将文件的快照放入暂存区域 à 提交更新,找到暂存区域的文件,将快照永久性存储到

Git 仓库目录。

下载安装

1 从Git官网直接 https://git-scm.com/downloads下载安装程序

2 安装完成后,命令行输入“git

--version”,显示如下信息表示安装成功。


3 设置用户信息,用户名称与邮件地址,每一个Git的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改

$ git config --global user.name "Your Name"

$ git config --global user.email "  email@example.com "

注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都 会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

4 检查配置信息

git config --list


Git仓库

什么是Git仓库  

可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

把想让git管理的文件放入此仓库下,放到其他地方Git再厉害也找不到你想管理的文件

创建Git仓库

有两种方法创建Git仓库

1 通过$ git init命令在现有目录中初始化仓库


该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的Git仓库中所有的必须文件,就是Git的版本库。

  如果你是在一个已经存在文件的文件夹(而不是空文件夹)中初始化Git仓库的话,

文件并不会被跟踪,通过git add 命令来实现对指定文件的跟踪,然后执行git

commit提交

创建Git仓库

2 从一个服务器克隆一个现有的 Git 仓库

$ git clone https://github.com/test/test

在当前目录下创建一个名为“test”的目录,并在这个目录下初始化一个 .git 文件夹,从远程仓库拉取下所有数据放入 .git 文件夹,然后从中读取最新版本的文件的拷贝。

如果进入到这个新建的“test”文件夹,发现所有的项目文件已经在里面了,并且都被git管理起来了,直接使用即可,无需执行add和commit命令。

也可以自定义本地仓库的名字,使用如下命令:

$ git clone https://github.com/test/test myTest

结果和上一个命令结果相同的,只是本地创建的仓库名字变为myTest。

Git 支持多种数据传输协议。上面使用的是 https:// 协议,也可以使用 git:// 协议或者使用

SSH

传输协议,比如 user@server:path/to/repo.git ,主要看git服务器的配置。

理解git文件的生命周期

工作区下的每一个文件分两种状态

已跟踪:指那些被加入了版本控制的文件,在上一次快照中有它们的记录,工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。

未跟踪:工作区中除已跟踪文件以外的所有其它文件,它们既不存在于上次快照的记录中,也没有放入暂存区

初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态

查看文件状态

$ git status

没有任何文件的打印结果

*工作目录相当干净,当前目录下没有出现任何处于未跟踪状态的新文件,否则Git 会在这里列  出来;*所有已跟踪文件在上次提交后都未被更改过;*该命令还显示了当前所在分支,并告诉你这个分支同远程服务器上对应的分支没有偏离。 分  支  名是“master”,这是默认的分支名

将文件添加到git版本库

$ git add xxx

git add 命令使用文件或目录的路径作为参数,如果参数是目录的路径,该命令将递归地跟踪该目录下的所有文件。

使用命令 git add 开始跟踪一个文件,即把文件加入到git版本库的暂存区,将此文件变为已跟踪


被跟踪文件进入暂存状态,如果此时提交,那么该文件此刻的版本将被留存在版本库中。


暂存已修改文件

$ git add xxx

现在我们新建一个XXX.txt文件,并通过add命令将其设置为被跟踪,然后再修改XXX.txt文件内容。

Changes not staged for commit表示说明已跟踪文件的内容发生了变化,但还没有放到暂存区。

要暂存这次更新,需要运行 git

add 命令

$git add这是个多功能命令:

1 可以用它开始跟踪新文件

2把已跟踪的文件放到暂存区

Git add注意事项

如果你现在提交,那么提交的版本是你最后一次运行 git

add 命令时的那个版本,而不是在工作目录中的当前版本。所以,运行了 git

add 之后又作了修订的文件,需要重新运行 git

add 把最新版本重新暂存起来

忽略文件

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表(比如日志文件,或者编译过程中创建的临时文件等)

创建一个名为 .gitignore 的文件,列出要忽略的文件模式

$ cat .gitignore

*.[oa]

*~

第一行告诉 Git 忽略所有以 .o 或 .a 结尾的文件。

第二行告诉 Git 忽略所有以波浪符(~)结尾的文件

tips:GitHub已经为我们准备了各种配置文件

https://github.com/github/gitignore

文件 .gitignore 的格式规范如下:

1 所有空行或者以 # 开头的行都会被 Git 忽略。

2 可以使用标准的 glob 模式匹配。

3 匹配模式可以以(/)开头防止递归。

4 匹配模式可以以(/)结尾指定目录。

5 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

所谓的 glob 模式是指 shell

所使用的简化了的正则表达式

1 星号(*)匹配零个或多个任意字符

2 [abc]匹配任何一个列在方括号中的字符

  (这个例子要么匹配一个a,要么匹配一个b,要么匹配一个c)

3 问号(?)只匹配一个任意字符;

4 如果在方括号中使用短划线分隔两个字符,表示所有在这两  个字符范围内的都可以匹配

  (比如 [0-9] 表示匹配所有0 到 9 的数字)

5 使用两个星号(*) 表示匹配任意中间目录

  (比如`a/**/z`可以匹配 a/z, a/b/z 或 `a/b/c/z`等)

查看已暂存和未暂存的修改

$ git diff &&$  git diffxxx

git diff 命令使用文件作为参数

此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,

也就是修改之后还没有暂存起来的变化内容。

将文件提交到git版本库

$ git commit –m “xxxxxxxxxxxxxxx”

使用命令 git

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

-m后面输入的是本次提交的说明,可以输入任意内容,最好是有意义的,这样你就能从历史记录里方便地找到改动记录

tips:在此之前,请一定要确认还有什么修改过的或新建的文件还没有git

add过,否则提交的时候不会记录这些还没暂存起来的变化,这些修改过的文件只保留在本地磁盘。

所以,每次准备提交前,先用 git

status 看下,是不是都已暂存起来了, 然后再运行提交命令 git commit

重新将文件提交到git版本库

$ git commit –amend –m “xxxxxxxx”

有时候提交完了发现漏掉了几个文件没有添加,或者提交信息写错了。此时,可以运行带有 --amend 选项的提交命令尝试重新提交。

这个命令会将暂存区中的文件提交。

如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令),那么快照会保持不变,而你所修改的只是提交信息

跳过使用暂存区域

$ git commit –a –m “xxxxxxxxxxxxxxx”

每次提交文件都需要git addàgit

commit,有没有更简单的方式呢?

给 git

commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git

add 步骤

查看已暂存和版本库的修改

$ git diff –-cached(staged )  && git diff –-cached(staged )xxx

此命令比较的是暂存区域快照和版本库之间的差异

移除文件

$ git rm xxx

git rm命令使用文件或者目录的名字,也可以使用 glob 模式

要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除,然后提交。

可以用git rm命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。

简单地从工作目录中手工删除文件,运行 git

status 时就会在 “Changes not staged for commit” 部分(也就是 未暂存清单)看到


$ git rm –-cached xxx

把文件从 Git 仓库中删除,仍然保留在当前工作目录中,换句话说,你想让文件保留在磁盘,但是并不想让

Git 继续跟踪,比如你忘记添加 .gitignore 文件,不小心把.class这样的编译生成文件添加到暂存区时

重命名文件

$ git mv xxx1 xxx2

其实,运行 git

mv 就相当于运行了下面三条命令:

$ mv README.md README

$ git rm README.md

$ git add README

查看提交历史

$ git log

工作一段时间之后,如果你想查看提交历史,可以使用git

log命令

按提交时间列出所有的更新,最近的更新排在最上面。

会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明

查看提交历史的其他格式

$ git log --pretty=oneline 显示每次提交的简略信息

$ gitlog –p  显示每次提交的内容差异,可以加上-1来仅显示最近一次提交,除了显示基本信息之外,还附带了每次commit的变化

$ git log  --stat  显示每次提交的简略的统计信息

$ git log --since=2.weeks  列出所有最近两周内的提交,可以设置多种格式,比如说具体的某一天 “2008-01-15”,或者是相对地多久以前 “2years

1 day 3 minutes ago”。

暂存区和版本库回退

$ git reset HEAD xxxxxxx&&  $gitreset HEAD^  

git reset 命令使用文件作为参数,或者用^ 

上一个版本就是HEAD^,上上一个版本就是HEAD^^,往上100个版本HEAD~100 reset HEAD xxxx

暂存区回退 $ git reset HEAD xxxxxxx

暂存区和版本库回退 $ gitreset HEAD^ 

$ git reset --hard HEAD^

版本库回退

--hard会让工作区的文件一起回退

版本找回

$ git reset --hard 1094a

参数为commit id  1094a,版本号没必要写全,前几位就可以了,Git会自动去找

版本回退之后用git

log是再也找不到提交历史了,也就无法找到commit id,

这个时候可以用git reflog来查看你的每一次命令

撤消工作区修改

$ git checkout –

xxxx

参数为文件

如果你并不想保留对 xxx.txt 文件的修改怎么办?

该如何方便地撤消修改 ,将它还原成上次提交时的样子(刚克隆完的样子,刚把它放入工作目录时的样子)?

xxx修改后还没有被放到暂存区,撤销修改就回到和版本库一模一样的状态;

其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。


Git分支

Git和传统的版本控制工具最大的区别在于分支,学习分支才能说是真正的掌握git的使用。

其他版本控制工具都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支很慢,但是在git上,无论创建、切换和删除分支,Git都很快完成。

大多数版本控制系统在创建分支时,将所有的项目文件都复制一遍,并保存到一个特定的目录。

完成这样的过程通常需要好几秒钟,有时甚至需要好几分钟,项目越大,所需时间的越长。

在 Git 中,基于Git的数据存储方式,任何规模的项目都能在瞬间创建新分支,而且分支合并也同样的简单和快速。

所以使用Git,鼓励频繁地创建和使用分支做不同的任务。


Git分支基础知识

我们假设现在有一个工作目录,里面包含了三个将要被暂存和提交的文件。

暂存操作会为每一个文件计算校验和(SHA-1 哈希算法),然后会把当前版本的文件快照保存到 Git 仓库中(Git 使用

blob

对象来保存它们),最终将校验和加入到暂存区域等待提交


当使用 git

commit 进行提交操作时,Git 会先计算每一个子目录的校验和,然后在

Git 仓库中这些校验和保存为树对象。

随后,Git 便会创建一个提交对象,该提交对象会包含一个指向快照的指针,还包含了作者的姓名和邮箱、提交时输入的信息、指向它的父对象的指针以及包含指向这个树对象的指针。



每次提交,Git 会保存一个提交对象,多次提交之后,那么这次产生的提交对象会包含一个指向上次提交对象(父对象)的指针


每次提交,Git都把它们串成一条时间线。

截止到目前,只有一条时间线,在Git里, 这个分支叫主分支(master),就是GIt默认分支,它就跟其它分支完全没有区别。

Git 的分支,本质上是指向提交对象的可变指针

Git 是怎么知道当前在哪一个分支上?

很简单,它有一个名为 HEAD 的特殊指针,可以将 HEAD 想象为当前分支的别名,HEAD指向的就是当前分支。

一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,

就能确定当前分支,以及当前分支的提交点:


每次提交(commit),master分支都会向前移动一步,随着你不断提交,master分支的线也越来越长


Git分支理解

当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,

通过checkout命令再把HEAD指向dev,就表示当前分支在dev上:


从现在开始,对工作区的修改和提交就是针对dev分支了,

提交一次(commit),dev指针往前移动一步,而master指针不变


假如我们在dev上的工作完成了,我们切换到master分支的时候,可以看到工作区文件是之前的

样子,所以切换分支不仅使HEAD指回master 分支,而且将工作目录恢复成 master 分支所指向的快照内容


现在我们可以把dev合并到master上,合并就是把master指向dev的当前提交,就完成了合并:


合并完分支后,可以删除dev分支。

删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支


Git分支操作

1 创建分支,要确定在哪个分支上创建子分支

$ git checkout -b dev

查看当前分支,当前分支前面会标一个*号

$ git branch


现在在dev分支上正常提交,比如对hellodongnao.txt做个修改,加上一行,然后提交


3现在我们需要将dev分支合并到master分支

  现在切换到master分支上,查看文件还是master之前的提交状态,因为那个提交是在dev分支上,而master分支此刻的提交点并没有变。

$ git merge dev

git merge命令用于合并指定分支到当前分支


合并后,再查看文件内容,就可以看到,和dev分支的最新提交是完全一样的。

4 合并完成后,可以删除dev分支了

$ git branch -d dev

分支冲突解决

合并操作不会如此顺利,

如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,合并它们就会出问题。

现在我们重复上面分支的操作

1 创建一个devOne分支

2 在devOne分支上进行修改和提交操作

3 切换回master分支,对同一个文件进行修改和提交操作

4 合并devOne分支

5 删除devOne分支

HEAD指向master 分支,在======= 的上半部分,而 devOne分支在 ======= 的下半部分。

你可以选择使用由 =======分割的两部分中的一个,也可以自行合并这些内容。


分析问题出现的原因:既在devOne分支上做了修改提交,也在master分支上对同一文件做了提交,导致合并devOne分支的时候出现了问题。

发生冲突了怎么办?

hello.txt合并发生了冲突,手动解决后,对每个文件使用 git add 命令来将其标记为冲突已解决冲突再提交。


非Fast forward合并

$ git merge --no-ff

-m “xxxxxx" devTwo

因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去

我们之前说的合并分支时,Git会用Fast

forward模式,但这种模式下,删除分支后,会丢掉分支信息。

现在我们不用Fast

forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

1 创建一个devTwo分支

2 在devTwo分支上进行修改和提交操作

3 切换回master分支,用非Fast

forward的方式合并devTwo分支

4 删除devTwo分支

$ git log --graph --pretty=oneline --abbrev-commit

查看分支历史合并情况


用Fast forward模式,分支历史上就可以看出分支提交信息和分支的信息


自动非Fast forward合并

Git也会自动使用非Fast forward模式,如分支分叉的情况,git会自动使用非fast模式


这和之前合并 devTwo分支的时候看起来有一点不一样,开发历史从一个更早的地方开始分叉开来。

所以Git 帮我们做了一些额外的工作,出现这种情况的时候,Git 会使用两个分支的末端所指的快照以及这

两个分支的工作祖先(分叉点),做一个简单的三方合并。

Git也会自动使用非Fast forward模式,如分支分叉的情况,git会自动使用非fast模式


rebase

Git中除了合并,还有一种方式可以进行分支合并,就是rebase,你可以使用 rebase 命令将某一分支上(devRebase)的所有修改都移至另一分支上(master)

$ git checkout devRebase

$ git rebase master

1 首先找到这两个分支(当前分支 devRebase 、变基操作的目标分支master)的最近共同祖先 a6081ce

2 对比当前分支相对于该祖先的全部提交,提取出来存为临时文件,相当于删除这些提交,在历史中也查不到信息了

3 然后将当前分支devRebase指向目标xx1,

最后将之前另存为临时文件的修改依序应用,生成新的提交xx2。


tips:此时下面虚线部分的东西已经没有了,392aa重新提交变成了xx2,现在提交变成了直线。

$ git checkout master

$ git merge devRebase

现在回到 master 分支,进行一次快进合并。


在rebase的过程中,也许会出现冲突。Git会停止rebase并会让你去解决冲突;

在解决完冲突后,需要执行git

add命令标记为以解决, 不需要执行 git commit

$ git rebase --continue

这样git会继续应用(apply)余下的补丁。

可以用--abort参数来终止rebase的操作,并且分支会回到rebase开始前的状态

$ git rebase --abort

Rebase优点

变基使得提交历史更加整洁,向远程分支推送时能保持提交历史的整洁。

你首先在自己的分支里进行开发,当开发完成时你需要先将你的代码变基到origin/master上,

然后再向主项目提交修改。

这样的话,项目的维护者就不再需要进行整合工作,只需要快进合并。

使用的时候要注意,不要对在你的仓库外有副本的分支执行变基!

变基操作的实质是删除一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。如果你已经将提交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用 git

rebase 命令重新整理了提交并再次推送,你的同事因此将不得不再次将他们手头的工作与你的提交进行整合,接下来你还要拉取并整合他们修改过的提交。

Rebase与非Fast forward对比


变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起。

理解变基就是将提交变成直线,然后直接快速合并。

注意无论是通过变基,还是通过非fast合并,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。

到底合并还是变基好?

1 如果你想看仓库的提交历史记录实际发生过什么,就算合并产生的提交历史是一团糟也没关系,

觉得它是历史文档,不能乱改,能随时查阅发生的事情,那就用非fast方式。

2 如果认为提交历史是项目过程中发生的事,只看结果,方便查阅,就用rebase。

所以看你和团队的需求

建议是对未推送给别人的本地修改执行变基操作清理历史,对已推送至别处的提交不要执行变基操作

暂存分支

$ git stash

当程序出现bug时,你就需要新建一个临时分支来修复,修复后,合并分支,然后将临时分支删除,但是你当前还在子分支上进行的工作还没有提交,而且只开发到一半,还不能提交。但是bug需要紧急修复,这个时候怎么办?

Git提供了一个stash功能,可以把当前分支暂存起来,之后可以恢复继续开发

现在我们创建一个子分支来修复bug。

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


2 现在修复bug,需要把“hello devTwo

branch”改为“hello devTwo branch

to bug”,然后提交:


3 修复完成后,切换到master分支并合并bug001分支

4 删除bug001分支

Bug修复完成了,我们回到devThree分支继续之前的开发

1 查看我们的暂存分支

$ git stash list

2 恢复我们的暂存分支

  a:一是用gitstash apply xxx恢复,stash内容并不删除,还需要git stash

drop来删除;

  b:另一种方式是用gitstash pop,恢复的同时把stash内容也删了:

3 我们接着完成devThree的工作

删除已经提交(未合并)的分支

$ git branch -D xxxxx

1 我们新建了 一个分支,已经完成了并提交(commit)的开发,但是这个时候不需要此需求了,应该把此分支删除。


补丁patch

补丁并不是针对所有代码的修改,只是针对于局部的修改。

在代码的维护中,如果只修改一部分代码,需要将代码完整的克隆下来,可是修改的只是很小的一部分;在这种情况下可以将一些代码的补丁信息发送给开发者,开发者收到之后知道那些代码被修改了,这样就可以使用一个极低的开销实现代码的修改操作

在git中提供了两种补丁方式

  1使用gitdiff生成标准的patch

  2 使用git format-patch声明git专用的patch

Git diff生产标准的patch

A 贡献者

1 创建一个testPatchDiff分支

2 在testPatchDiff分支上进行代码修改

3 使用git diff xx 查看修改

4 在testPatchDiff分支上进行提交

5 使用git diff master> testDiff创建补丁信息testDiff

6 删除testPatchDiff分支

B 开发者

    1 cat testDiff查看有哪些修改

2 切换到master分支

3 创建一个新的applyPatchDiff分支

4 使用git apply testDiff 应用补丁信息testDiff

5在applyPatchDiff分支上进行提交补丁操作

6 切换回master分支合并applyPatchDiff分支

7 删除applyPatchDiff分支

git format-patch声明git专用的patch

A 贡献者

1 创建一个testPatchFormat分支

2 在testPatchFormat分支上进行代码修改

3 使用git diff xx 查看修改

4 在testPatchFormat分支上进行提交

5 使用git format-patch master与原始代码做一个比较,比较之后会自动生成补丁文件

     6删除testPatchFormat分支

B 开发者

     1cat 0001-testPathcFormat.patch查看有哪些修改(像是一封邮件,可以将文件粘贴  进电子邮件客户端,也可以通过命令行gitsend-email发送它)

2 切换到master分支

3 创建一个新的applyPatchFormat分支

4 使用git am 0001-testPathcFormat.patch应用补丁信息

5 切换回master分支合并applyPatchDiff分支

6 删除applyPatchFormat分支


补丁两种方式比较

git diff生成的Patch兼容性强。如果你修改的代码不是Git管理的版本库,那么必须使用git

diff生成的patch才能让你的代码被项目的维护人接受。

但是如果你是向公共的开发社区进行代码的补丁更正,建议使用git format-patch,这样不仅标准,而且也可以将作者的信息公布

GitFlow理解

GitFlow 是由

Vincent

Driessen 提出的一个

git操作流程标准,包含如下几个关键分支:

master:主分支,非常稳定的,不用来开发和发布,只用来跟踪已经发布的代码;

develop:主开发分支,包含确定即将发布的代码;开发都在这个分支;

    到发布时,再合并到release上;

feature:新功能分支,一般一个新功能对应一个分支,对于功能的拆分需要比较合理,以  避免一些后面不必要的代码冲突;

release:发布分支,发布时候用的分支,测试时候发现的

bug直接 在这个分支进行修复;

hotfix:紧急修 bug

的时候用;


我们想在开发要开发一个新功能,基于develop分支创建feature分支

完成后再合并到 develop 分支上,等待发布



当需要发布时,我们从 develop 分支创建一个 release 分支 

然后这个 release 分支会发布到测试环境进行测试,如果发现问题就在这个分支直接进行修复。


发布结束后,这个 release 分支会合并到

develop

和 master

分支,从而保证不会有代码丢失


hotfix 分支的作用是紧急修复一些 Bug。它们都是从

master

分支上建立,修复结束后再合并到

develop

和 master

分支上。

GitFlow的好处

并行开发:

每个新功能都会建立一个新的 feature分支,从而和已经完成的功能隔离开来,而且只有在新功能完成开发的情况下,其对应的 feature分支才会合并到主开发分支(develop分支)

协作开发:

每个 feature分支多人协同开发。

发布阶段:

当 feature 开发完成的时候,它会被合并到 develop 分支,这个分支主要用来暂时保存那些还没有发布的内容,所以如果需要再开发新的 feature,我们只需要从 develop 分支创建新分支,即可包含所有已经完成的 feature 。

紧急修复:

hotfix(bug) 分支,这种类型的分支是从master分支上创建出来并做一个紧急的修复,而且这个紧急修复只影响这个已经发布的 版本,而不会影响到你正在开发的新 feature。

Git远程仓库

GitHub是一个免费的服务器,这个网站就是提供Git仓库托管服务的,所以,只要注册一个GitHub账号,就可以免费获得Git远程仓库

 注意GitHub上免费托管的Git仓库,任何人都可以看到

有了GitHub帐号之后,并不是说就可以直接使用了,还需要创建SSH

Key。

1 在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Git

Bash,创建SSH Key:

$ ssh-keygen -t rsa -C "youremail@xxx.com"


里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥,id_rsa是私钥,id_rsa.pub是公钥

2 登陆GitHub,打开“Account settings”,“SSH and GPG keys”页面:

然后,点“New Ssh key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容

那么此时表示已经和GitHub之间建立好了一个安全链接。

由于ssh存在,GitHub才能进行用户识别。

GitHub允许你添加多个Key。

添加远程库

在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过远程仓库来协作。

1首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库。

2 在Repository name填入testGit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库

现在设置的仓库名称为testGit,仓库创建完成之后会给出两种链接方式

a: https://github.com/xx/testGit.git

b: git@github.com:xx/testGit.git

使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https。

3目前,在GitHub上的这个testGit仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联。

现在,把GiuHub与本地仓库关联,在本地的testGit仓库下运行命令

$ git remote add origin git@github.com:xxxxxxx/testGit.git

xxxxx为你自己的GitHub帐号

远程库仓库的名字就是origin,这是Git默认的叫法,也可以改成别的

此时已经和远程仓库建立了链接,但是远程仓库里面并没有本地仓库的内容

4 下一步,就可以把本地库的所有内容推送到远程库上:

$ git push -u origin master

把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令以后直接运行

$ git push origin master

把本地master分支的最新修改推送至GitHub

5 查看GitHub是有添加了本地内容

tips:当你第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:

  Theauthenticity of host 'github.com (xx.xx.xx.xx)'

can't be established.

  RSAkey fingerprint isxx.xx.xx.xx.xx.

  Areyou sure you want to continue connecting (yes/no)?

这是因为Git使用SSH连接,而SSH连接在第一次验证GitHub服务器的Key时,

需要你确认GitHub的Key的指纹信息是否真的来自GitHub的服务器,输入yes回车即可。

这个警告只会出现一次,后面的操作就不会有任何警告了

提交文件到远程仓库

1 修改xxx.txt并提交

2 此时的修改都属于本地仓库master分支,下面提交到远程仓库master分支

$ git push origin master

远程仓库其他操作

使用https建立一个test远程仓库 

$ git remote add test https://github.com/xxxxx/xxxGit.git

查看远程仓库信息,如果没有推送权限,就看不到push的地址

$ git remote &&  $gitremote -v

切换远程仓库

$ git remote set-url

origin git@github.com:xxxxx/xxxGit.git

删除远程仓库

$ git remote rm  test

从远程库克隆

之前先有本地库,后有远程库的时候,如何关联远程库。

现在先创建远程库,然后,从远程库克隆。

1 首先,登陆GitHub,然后,在右上角找到“Create

a new repo”按钮,创建一个新的仓库helloGit。

我们勾选Initialize this repository with a README表示自动为用户进行仓库的初始化,并且这样GitHub会自动为我们创建一个README.md文件。

2 现在,远程库已经准备好了,下一步是用命令git

clone克隆一个本地库,不要在xxxGit目录下操作,直接换一个新目录helloGit。

$ git clone git@github.com:xxxxx/helloGit.git

3 再尝试下提交文件到远程仓库

克隆其他开源项目

不要认为GitHub就是一个远程仓库,它上面有不少开源项目,如bootstrap,mybatis

  如:https://github.com/mybatis

1 但是这个上面下载下来的代码是不能够进行修改的,因为这个主文件只能由用户发出补丁,而后由开发者进行修改。如果要是参考源码或者修改,可以将项目克隆过来(fork)

2 进入自己的帐号下,获取到远程仓库的地址,之后可以在本地仓库中将代码克隆下来。

$ git clone git@github.com:xxxxx/mybatis.git

tips:如果从mybatis的作者的仓库地址克隆,因为没有权限,你将不能推送修改。

协同开发

单分支开发

    1 A修改其中一个文件并commit和push

  2 B修改另外一个文件并commit和push(能不能push成功?)

两个开发者并没有编辑同一个文件,但Git要求在本地合并提交。B必须抓取A的改动并合并它们,才能被允许推送。 

$ git fetch <远程主机名>

//这个命令将某个远程主机的更新全部取回本地

$ git fetch <远程主机名>

<分支名> //取回特定分支的更新,可以指定分支名

3 B执行fetch取回服务器的更新(可以通过git

log –p FETCH_HEAD查看更新信息)



4 B合并远程分支到自己的master分支

$git merge origin/master


6 于此同时A还在开发,commit之后准备push

7 A想要push,也得先执行fetch拉取服务器的更新并合并再提交


分支其他操作

分支更名

$ git branch –m xxx1 xxx2  xxx1为原来分支名称,xxx2为新分支名称

查看分支

$ git brance –a  查看全部分支,包括远程和本地

$ git brance –r  查看远程分支

$ git brance –l  查看本地分支

删除远程分支

$ git push origin --delete xxxxx

标签

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

Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。


创建标签

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


$ git tag xxxx

默认标签是打在最新提交的commit上的。如果想在之前的commit上打标签,先找到历史提交的commit

id,然后打上就可以了:

$ git tag v0.9 67cda3

可以用命令git

tag查看所有标签:

$ git tag

还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:

 $git tag -a xxxx -m “xxxxx" xxxxx

查看标签信息

$ git show xxx

操作标签

本地标签删除

$ git tag -d xxxx


推送本地标签到gitHub

$ git push origin xxxx

推送全部尚未推送到远程的本地标签

$ git push origin --tags


删除远程仓库标签

1 先删除本地标签

$ git tag -d xxxx

2 从远程删除

$ git push origin :refs/tags/xxxxxx



搭建GitLab服务器

GitHub是一个免费的服务器,这个网站就是提供Git仓库托管服务的,如果公司开发使用的话,会有几个问题

  1网络不稳定

  2代码是公开的,大家都可以查看

如果你需要一个私有的托管服务,支付每个月7美元购买5个私有库,想要更多的私有仓库则要交更多的钱

最好的方法就是在你的服务器上运行 Git。不仅你能够省去一笔钱,你还能够在你的服务器有更多的操作。

在linux上有两种方式部署git服务器

1 使用名为 GitLab 的

GUI

工具

2 运行一个纯Git 服务器


GitLab 是一个非常优秀的项目,这是一个开源项目,允许用户在自己的服务器上运行类似于

GitHub 的项目管理系统,使用

GitLab 为团队成员或公司运行类似于

GitHub 的服务,可以使用

GitLab 开发私有项目。

安装之前,请确保你的服务器是否安装了

ssh    rpm -qa|grep -E

"openssh"

防火墙  rpm-qa|grep-E "firewalld"

wget    rpm -qa|grep -E

"wget"

1 安装 GitLab 之前,需要配置

SMTP

电子邮件服务器,以便

GitLab 可以在需要时随时推送电子邮件。官方推荐使用

Postfix。先在你的服务器上安装

Postfix

# yum install postfix  安装命令

# systemctl enablepostfix  开机自启动

# systemctl startpostfix  启动postfix

2添加GitLab镜像源,其他镜像下载地址:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/

# wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm

3 安装gitlab

# rpm -i

gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm

4 修改gitlab配置文件指定服务器ip和自定义端口

# vim  /etc/gitlab/gitlab.rb

    external_url `http://192.168.1.149:8900`    服务器ip和未被占用的端口

    unicorn[‘port’]=8899        默认8080,设置未被占用端

5 重置gitlab配置文件

# gitlab-ctl

reconfigure

6 重启gitlab

# gitlab-ctl

restart

7 访问gitlab,直接输入上面配置的ip加端口访问即可

   初始账户: root 密码:5iveL!fe

8 设置gitlab发信功能,发信系统用的默认的postfix,smtp是默认开启的,两个都启用了,两个都不会工作,可以自己选择

  a 设置关闭smtp,开启postfix

# vim /etc/gitlab/gitlab.rb

   gitlab_rails['smtp_enable']

= false

b 关闭postfix,设置开启smtp

   https://docs.gitlab.com/omnibus/settings/smtp.html

测试是否可以邮件通知:登录并添加一个用户,我这里使用qq邮箱添加一个用户,登录qq邮箱,

可以收到邮件通知(也可在linux执行echo "test mail"|mail -s "postfix mail title"   123456789@qq.com)

如果收不到,请查看垃圾邮箱或者检查邮件是否被拦截并删除,如果有请添加到白名单

并删除用户再重新添加用户就可以收到了,否则请检查邮件日志并做好相关设置

tips:

1 如果gitlab报502错误,一般是权限问题,解决方法:# chmod -R

755 /var/log/gitlab

 如果还不行,请检查你的内存,安装使用GitLab需要至少4GB可用内存,否则出现各种诡异的问题,

 而且在使用过程中也经常会出现500错误.

2 gitlab-ctl reconfigure:

  Errorexecuting

action `run` on resource 'execute[/opt/gitlab/embedded/bin/initdb-D /var/xxxx‘

 文件/etc/passwd的权限是600,给予644权限后,解决问题

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

推荐阅读更多精彩内容