Git实用分享
概述
Git 对程序员来说太重要了,Git 不仅有些基础操作是必须要会的。
Git必知
Git进行版本控制的基础
- 文件夹
- 暂存区
- 本地 git 文档库
- 远程 git 文档库:远程 git 文档库其实可以完全和网络没有关系,「远程 git 文档库」可以和「本地 git 文档库」存在于同一台的计算机中。

Git追踪文件的方式
- tracked: 被 tracked 的文件或者文件夹会被 git 追踪是否被修改
- ignored: ignored 状态是主动需要被忽略的,常见的就是 IDE 的一些文件
- untracked:一般是那种新建的文件或者子文件夹
|
|
其他
- commit: 相当于文档库的代码版本
- HEAD: HEAD 就是当前活跃分支的游标, 形象的记忆就是:你现在在哪儿,HEAD 就指向哪儿,所以 Git 才知道你在那儿

Git常用命令
|
|
Git基础操作
以下是最基础的 git 操作命令, 新建一个文件, 然后检查以下文件夹内的情况, 在把新建的文件加入「暂存区」, 在把「暂存区」的文件提交到「本地 git 文档库」。
|
|
使用git diff比较文件
git diff 的可以应用的场景比较多, 需要熟悉掌握。通过比较文件或者文件夹,可以找到自己修改过的地方。
|
|
git merge和git rebase的区别
合并时候开发分支多了几个 commit 节点,但是 master 分支并没有任何改变,相当于将开发分支的文件内容 copy 一份到 master 分支上, master 分支会沿着开发分支"快进"到开发分支最新的节点, 特点是不产生新的 commit 节点,不会留下合并记录。 下图所示, 虽然两个分支重叠在一起,但是还是属于两个分支。
Fast-forward merge合并状态

如果想留下合并记录可以使用 git merge –no-ff 分支名称, 这种方式又叫 3-way-merge。
merge之后留下了commit节点

表示将 master 和开发分支的最新 commit 节点的文件内容合并产生一个新的 commit 节点, 常见于 bug 分支和 master 分支同时有进行开发,git 会自动判断。
master同时也进行了开发

当自己的开发分支和 master 分支同时在开发的时候,这种时候需要保持开发分支和 master 分支经常性的同步,才不至于在最后合并的阶段处理一堆的冲突。按之前说的可以不断的用 git merge 来实现。其实没什么问题,只是项目的commit节点演进图会变得很复杂。
不断的merge

rebase 则是把一个分支的修改应用到当前的分支,并且可以得到比较清晰的演进图。
通过rebase可以得到比较清晰的演进图

如果master分支的commit落后开发分支的commit太多,并且这些commit节点的冲突比较多,此时用rebase的话就要逐个冲突commit进行解决,因此这种情况推荐使用merge。
git stash的用法
git stash 是将正在修改的文件保存了一个快照, 此时是开辟了新的空间来暂存这些记录, git stash 其实包含了两个动作:
- 存储文件夹中被git追踪的文件和文档库中最新文件版本的差异
- 把文件夹中被git追踪的文件还原成文档库中最新的文件版本
git log查看commit记录
git log 可以用于查看 commit 的记录,所以要求有比较清楚的 commit message 是很重要的,这样再回退到某个 commit 是很方便的。
|
|
关于 commit 的 message 的书写的规范, 希望大家遵守
|
|
回退的几个操作
git 有很好的回退机制, git reset、git checkout 和 git revert 是你的 Git 工具箱中最有用的一些命令。它们都用来撤销代码仓库中的某些更改,而前两个命令不仅可以作用于提交,还可以作用于特定文件。
git reset: 在提交层面上,reset 将一个分支的末端指向另一个提交。这可以用来移除当前分支的一些提交。比如,下面这两条命令让 hotfix 分支向后回退了两个提交。
|
|

git checkout
|
|

git revert
Revert 撤销一个提交的同时会创建一个新的提交。这是一个安全的方法,因为它不会重写提交历史。比如,下面的命令会找出倒数第二个提交,然后创建一个新的提交来撤销这些更改,然后把这个提交加入项目中。
|
|

操作远程git文档库
创建远程git文档库
可以在本地创建也可以在GitLab上直接创建
本地git文档库与远程git文档库的数据同步
git pull 拉代码 是为了使本地的远程 git 文档库的分支和远程 git 文档库的最新状态一致 其实是分了两个步骤,先是 git fetch 接着再使用 git merge,当然 merge 会使演进图比较复杂 也可以采用 rebase 为第二个步骤, git pull -r
git push 推代码 将本地的远程 git 文档库的代码推到远程 git 文档库 git push –set-upstream orgin 分支名称 可以设置本地git文档库的分支和远程git文档库的分支对应的关系 git remote -v 可以查看一下对应关系

Git协作的方式
集中式工作流
持续在 master 上进行开发, 所有修改提交到这个分支上。本工作流只用到 master 这一个分支。

功能分支工作流
根据开发的功能从 master 上切出新的分支进行开发, 功能开发隔离也让 pull requests 工作流成功可能, pull requests 工作流能为每个分支发起一个讨论, 在分支合入正式项目之前, 给其它开发者有表示赞同的机会。

Gitflow工作流
Gitflow 工作流通过为功能开发、发布准备和维护分配独立的分支,让发布迭代过程更流畅

Forking工作流
Fork的翻译可以是叉子或者是分支, 在Git系统里显然翻译成分支分叉是更合理的, 那么这样fork与branch又很像, fork是针对真个git文档库,而branch操作的对象是程序项目, 另外fork又和clone很像,因为都是操作文档库, 但是clone出来的文档库不会记录这个文档库的来源的, 而fork出来的文档库,会保留它的来源git文档库,将来这个fork得到的git文档库可以再合并到原来的git文档库, 然而fork操作如果离开了网络是不存在的,因为不是git程序原生的操作模式。

Forking 工作流是分布式工作流,充分利用了 Git, 在分支和克隆上的优势。可以安全可靠地管理大团队的开发者 developer,并能接受不信任贡献者 contributor 的提交。

Git alias设置
- 配置oh-my-zsh
- 查看alias
- 自定义
|
|
Git实战
合理的切出分支进行开发
git-sharing 里面需要增加一个文件 first.txt
|
|
开发新功能过程中要修bug
git-sharing 正在编辑一个文件 second.txt,然而被 pm 要求紧急删除 first.txt 文件的最后一行
|
|
几种常见的工作流的演示
Gitlab功能
观察commit演进图
这个演进图是远程文档库的演进图, 和本地文档库的演进图是不一样的

compare功能代替git diff

merge request的设置
由于是跟远程 master 分支进行合并, 所以请书写规范的 merge request 的信息, 方便 code review 以及问题的回溯。

Git Tips
- 仔细阅读git的错误提示
- 尽量使用命令行的操作方式, 减少 IDE 的依赖
- 多用git rm, 少用 rm a.txt | git add -A . 后者有丢代码的风险
- 多用 revert, 少用 git reset — hard, document/index/repository 级别
- 多久 commit 一次? 按功能来决定
- 经常性地和 master 做 rebase

参考资料
- UdaCity-UD775
- Git Help