一、git的协同工作流
中心式协同工作流
1、先把你本地提交的代码放到一边。
2、然后把服务器上的改动下载下来。
3、然后在本地把你之前的改动再重新一个一个地做 commit,直到全部成功
4、如果有冲突,需要先解决冲突
这种工作流适合小项目小团队
功能分支协同工作流
分功能开发(把每个功能隔离开来)
并且每个功能下又会有很多人员在开发
1、首先使用 git checkout -b new-feature 创建 “new-feature”分支。
2、然后共同开发这个功能的程序员就在这个分支上工作,进行 add、commit 等操作。
3、然后通过 git push -u origin new-feature 把分支代码 push 到服务器上。
4、其他程序员可以通过git pull --rebase来拿到最新的这个分支的代码。
5、最后通过 Pull Request 的方式做完 Code Review 后合并到 Master 分支上
上图紫色的分支就是功能分支,合并后就会像上面这个样子
GitFlow 协同工作流
整个代码库中一共有五种分支。
Master 分支。也就是主干分支,用作发布环境,上面的每一次提交都是可以发布的。
Feature 分支。也就是功能分支,用于开发功能,其对应的是开发环境。
Developer 分支。是开发分支,一旦功能开发完成,就向 Developer 分支合并,合并完成后,删除功能分支。这个分支对应的是集成测试环境。
Release 分支。当 Developer 分支测试达到可以发布状态时,开出一个 Release 分支来,然后做发布前的准备工作。这个分支对应的是预发环境。之所以需要这个 Release 分支,是我们的开发可以继续向前,不会因为要发布而被 block 住而不能提交。
一旦 Release 分支上的代码达到可以上线的状态,那么需要把 Release 分支向 Master 分支和 Developer 分支同时合并,以保证代码的一致性。然后再把 Release 分支删除掉。
Hotfix 分支。是用于处理生产线上代码的 Bug-fix,每个线上代码的 Bug-fix 都需要开一个 Hotfix 分支,完成后,向 Developer 分支和 Master 分支上合并。合并完成后,删除 Hotfix 分支。
GitLab Flow
它在GitHub Flow上做了一些优化引入环境分支(预发布(Pre-Production)和生产(Production)分支)
有些时候,我们还会有不同版本的发布,所以,还需要有各种 release 的分支
二、基础
clone
# 克隆项目
$ git clone [url] [自定义本地仓库名称]
# Git 支持多种数据传输协议
https:// 协议 、git:// 协议、SSH传输协议
# 生成一个git的SSH公钥方便后面使用
ssh-keygen -t rsa -C <自己Gitlab账号的邮箱>
【参考】https://www.jianshu.com/p/9317a927e844
status
# 检查当前文件状态
$ git status
# git status 输出很详细 可以使用下面的命令以一种更为紧凑的格式输出
$ git status -s 或 $ git status --short
新添加的未跟踪文件前面有 ?? 标记
新添加到暂存区中的文件前面有 A 标记
修改过的文件前面有 M 标记
如果出现了两个MM,那么左面的M表示该文件被修改了并放入了暂存区,而右边的M表示该文件被修改了但是还没放入暂存区
add
# 跟踪新文件 添加指定文件到暂存区
$ git add [file1] [file2] …
# 添加指定目录到暂存区,包括子目录
$ git add [dir]
# 添加当前目录的所有文件到暂存区
$ git add .
# 把 git add 这个命令理解为“添加内容到下一次提交中”
diff
# 查看已暂存和未暂存的修改 它和 git status命令类似 但是更详细
# 查看尚未暂存的文件更新了哪些部分 此命令比较的是工作目录中当前文件和暂存区域快照之间的差异
$ git diff
# 查看已暂存的将要添加到下次提交里的内容
$ git diff –cached 或 $ git diff --staged
commit
# 提交更新
# 将暂存区的数据提交到本地仓库
$ git commit 或 $ git commit -v
# 可以在 commit 命令后添加 -m 选项,将提交信息与命令放在同一行
$ git commit -m [自定义的提交信息]
# 跳过使用暂存区域 从而跳过 git add 步骤
$ git commit -a -m [自定义的提交信息]
rm
# 移除文件 即从暂存区域中移除 并连带从工作目录中删除指定的文件(从本地文件夹中删除文件)
$ git rm [file] [file]…
# 如果删除之前修改过并且已经放到暂存区域的数据 (这样的数据不能被 Git 恢复)
$ git rm -f [file] [file]…
# 把文件从暂存区域中移除 但希望保留在当前工作目录上
$ git rm -cached [file] [file]…
reset
# 取消暂存的文件
$ git reset HEAD [file]
这个命令貌似和 git rm -cached [file] [file]… 命令效果一样
# 撤消对文件的修改(我自己的理解是把已经修改的文件恢复和本地仓库最后一次push完后此文件的状态一样,即恢复)
$ git checkout -- [file]
MV
# 移动文件
# 不像其它的 VCS 系统,Git 并不显式跟踪文件移动操作
# 在 Git 中对文件改名
$ git mv [url/oldname] [url/newname]
其实它相当于运行了
$ git rm [url/oldname] $ git add [url/newname]
撤销操作
注意:有些撤消操作是不可逆的使用是请注意
# 补充漏提交的文件,或者修改提交信息
$ git commit -m [自定义提交信息] --amend
如果自上次提交后你未做任何修改,那么此命令指示修改提交信息
# 查看提交历史
$ git log
一个常用的选项 -p 用来显示提交的内容差异。你还可以加上 -2 来显示最近两次的提交
$ git log -p
如果你想看到每次提交的简略的统计信息,你可以使用 --stat 选项
$ git log -stat
另外一个常用的选项是 --pretty。 这个选项可以指定使用不同于默认格式的方式展示提交历史。另外还有 short,full 和 fuller 可以用。
但最有意思的是 format,可以定制要显示的记录格式。 这样的输出对后期提取分析格外有用 — 因为你知道输出的格式不会随着 Git 的更新而发生改变:
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number085bb3b - Scott Chacon, 6 years ago : removed unnecessary testa11bef0 - Scott Chacon, 6 years ago : first commit
远程仓库的使用
# 查看远程仓库
$ git remote [-v]
# 查看某一个远程仓库的更多信息
$ git remote show [remote-name]
# 添加远程仓库
$ git remote add <shortname> <url>
# 重命名远程分支
$ git remote rename <oldname> <newname>
# 移除一个远程分支
$ git remote rm <remote-name>
fetch 与 pull
# 从远程仓库中抓取与拉取
# 从远程仓库获取本地没有的数据
$ git fetch [remote-name]
这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。
必须注意 git fetch 命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作,它只会获取数据然后让你自己合并。有一个命令叫作 git pull 在大多数情况下它的含义是一个 git fetch 紧接着一个 git merge 命令。
# 如果你有一个分支设置为跟踪一个远程分支,使用如下命令来自动的抓取然后合并远程分支到当前分支
$ git pull
由于 git pull 的魔法经常令人困惑所以通常单独显式地使用 fetch 与 merge 命令会更好一些
# git push 并不会传送标签到远程仓库上,必须显式的推送标签,和共享远程分支类似
$ git push <remote-name> <tag-name>
# 可以使用带有 --tags 选项的 git push 命令,一次性推送很多标签到远程仓库
$ git push <remote-name> --tags
# 在 Git 中你并不能真的检出一个标签,因为它们并不能像分支一样来回移动。 如果你想要工作目录与仓库中特定的标签版本完全一样,可以使用 git checkout -b [branchname] [tagname] 在特定的标签上创建一个新分支
$ git checkout -b [branchname] [tagname]
# 推送到远程仓库
$ git push [remote-name] [branch-name]
tag
# 列出和查看标签
$ git tag
# 模糊查询标签
$ git tag -l <'标签关键字'>
# 创建轻量标签
$ git tag <tag-name>
# 创建附注标签
$ git tag -a <tag-name> -m <备注消息>
# 忘记给项目打标签,可以在之后补上标签
$ git tag -a <tag-name> <提交的校验和(或部分校验和)>
# 查看标签信息与对应的提交信息
$ git show <tag-name>
三、分支
branch
# 创建一个分支
$ git branch <branch-name>
# HEAD 表示一个指针,总是指向当前所在分支
# 切换分支
$ git checkout <branch-name>
以上两个命令简写形式
$ git branch -b <branch-name>
# 删除分支
$ git branch -d <branch-name>
# 查看每一个分支的最后一次提交
$ git branch -v
# 查看已经合并或尚未合并到当前分支的分支
$ git branch [--merged] [--no-merged]
如果要同步你的工作,运行 git fetch origin 命令。 这个命令查找 “origin” 是哪一个服务器,从中抓取本地没有的数据,并且更新本地数据库,移动 origin/master指针指向新的、更新后的位置。
push
# 推送。推送你要共享的分支到远程仓库上
$ git push <remote><branch>
【e.g】
# 推送本地的 serverfix 分支来更新远程仓库上的 serverfix 分支
$ git push origin serverfix
# 不想让远程仓库上的分支叫做 本地分支名称
$ git push <remote> <local-branch-name : remote-branch-name>
【e.g】
#将本地的 serverfix 分支推送到远程仓库上的 awesomebranch 分支
$ git push origin serverfix:awesomebranch
# 创建一个跟踪指定远程仓库上的分支
$ git branch -b <branch-nam> <remotenam/branch>
# 设置已有分支到一个新的远程分支
$ git branch [-u] [--set-upstream-to] <remotenam/branch>
# 查看设置的所有分支
$ git branch -vv
# 删除一个远程分支
$ git push <remote> --delete <remote-branch-name>
四、软件版本
五、修改历史图谱
个人总结:git rebase命令使git merge后的历史图谱是一条直线,而并没有分叉
rebase黄金定律
永远不要rebase一个已经分享的分支(到非remote分支,比如rebase到master,develop,release分支上),也就是说永远不要rebase一个已经在中央库中存在的分支.只能rebase你自己使用的私有分支
# 使历史图普为一条直线,避免污染历史图谱 (是分叉的历史图谱,变成只有一条直线的历史图谱)
$ git rebase <basebranch> <topicbranch> $ git checkout <basebranch> $ git merge <topicbranch>
# --no-ff参数(no fast forward的意思)
$ git merge [--no-ff] <branch-name>
# 把多个commit整合成一个commit
$ git merge <branch-name> --squash
# 比如你在dev分支为了一个小的功能或者idea连续提交了多个commits,这时你希望将这些commit合并为一个以免污染了git的历史信息,这时,你可以做的就是:找到这些个commits之前最早的basecommit,运行以下命令
$ git rebase -i <basecommit>
$ git pull --rebase