git

配置

git config --global "Your Name"
git config --global "Email Address"
git config --global credential.helper store    保存密码(每次要输密码/重复输密码)

初始化

git init

提交修改

git add <file>
git add -u 提交 work directory 中所有已 track 的文件至 staging area
git commit -m "descriptions"
git commit --amend 对最近一次的提交做内容修改
git commit --amend --author "user_name <user_email>" 修改最近提交用户名和邮箱

查看状态、比对

git status
git status -s 文件状态缩略信息, 常见 A: 新增; M: 文件变更; ?:  track; D: 删除
git diff <file>
git diff HEAD -- <file>                 查看工作区和版本库里面最新版本的区别
git diff --check <file>                 检查是否有空白错误(regex:' \{1,\}$')
git diff --cached <file>                查看已add的内容(绿M)
git diff branch1 branch2 --stat         查看两个分支差异
git diff branch1 branch2 <file...>      查看分支文件具体差异

查看历史版本、历史操作

版本回退、前进

撤销修改

删除与恢复

清理工作区未track也未ignore的文件或文件夹(如各种临时.swp, .patch文件等)

关联GitHub远程仓库(本地到远程)

克隆GitHub远程仓库(远程到本地)

分支管理:创建、切换、查看、合并、删除

解决合并冲突

分支管理:合并后删除分支也在 log 中保留分支记录

开发流程

Bug 分支管理(建立单独分支进行 bug 修复)

Feature 分支管理(建立单独分支添加新功能)

协作与分支推送

User 1:

User 2:

User 1:

标签管理(常用于版本管理):查看、创建、操作

rebase (换基)

rebase 在日常中常用功能主要是两个, 多人协同开发定期 rebase master 以及压缩某分支多个commit git rebase master 常见于多人开发, 每个开发人员从 master checkout 出自己的分支, 开发一段时间后提交至 master 之前最好 rebase 一下, 防止冲突, 就算真有冲突在本地解决好过强制提交, 开发流程中尽量保证 master 的干净整洁

举个例子: master 分支上有三个提交C1, C2, C3 某一时刻 usr1 在 C3 的 master 分支上 checkout 出新的分支, 用于开发服务端支持 ipv6 新特性, 并提交了 C4, C5

此时提交状态如下所示

某同事 usr2 修改了 master 上的内存泄漏错误, 并提交了 C6, C7, C8 三个 commit, 然后直接推送 origin/master (假设这个期间无其他人推新内容到 master) 此时提交状态如下所示

如果此时 usr1 希望将 ipv6 的新特性提交至 master, 那么在其直接 push origin master 时会提示 master 需要合并分支 ipv6_support 虽然 C4, C5 的改动内容完全独立于 C6, C7, C8 的改动 但 git 仍会抓取 C5 和 C8 的提交并产生一个新的 C9 commit (因两者分支的 base 不同), 如下图所示

如果是为了保证 master 提交记录的"干净完整" 或者是某分支不着急提交, 仍需要更多的测试与开发, 但又不想分支开发周期结束后"偏离"当初 checkout 的 master 分支太久远(容易造成更多的冲突) 可以考虑(定期)利用 rebase 来进行变基 即上面提到过的多人协同开发, 定期 rebase master 是个好习惯

结果提交状态如下所示

这种 rebase 在功能上类似将某分支所有的改动做成多个 patch 并依次打在指定的新 base 上 此时再提交 master 就不会产生抓取效果, 会将 C4' 和 C5' 直接提交至 master, 即 can be fast-forwarded, 同时也保证了 master 提交记录的整洁性 (注: 虽然 C4' 和 C5' 的内容和 C4, C5 完全一致, 但两者 base 不同, commit hash code 也完全不同)

某项目状态分支如下所示, 其中 Cn 的数字代表提交时间顺序

  • T1 某员工 urs1 从 C2 (master 分支) checkout 出一个新的分支用于开发某基础公共组件功能

  • T2 员工 usr1 开发完毕提交 C3, 然后继续在该分支上(或 checkout -b server) 开发服务端相关功能, 并提交 C4

  • T3 master 分支有更新, 其他同事 usr2 提交了 C5, C6 并推送到了 origin master

  • T4 员工 usr1 从 server 分支切回到 C3 公共基础的提交, 并创建新分支 client, 用于开发客户端功能, 并提交 C8, C9

  • T5 员工 usr1 从 client 分支切回到 server 分支继续开发服务端功能, 并提交 C10

此时该员工希望将客户端相关的功能合并到主分支并发布,但暂时并不想合并 server 中的修改,因为它们还需要经 过更全面的测试。 这时可以使用 git rebase 命令的 --onto 选项,选中在 client 分支里但不在 server 分支里的修改(即 C8 和 C9),将它们在 master 分支上重放:

得到如下图所示的提交状态 注: 其中 C3', C8', C9' 与 C3, C8, C9 的提交内容完全一样, 但是 hash id 是完全不同的

can be fast-forwarded

提交后分支状态如下

打 patch (补丁)

bundle (打包)

该命令会将 git 工程打包, 默认情况下会打包所有 commit 记录和 track 的文件 不同于简单粗暴 tar.gz 打包整个文件夹, bundle 只打包那些 push 过的记录 如某 git 工程下存在 .build 构建后的目录, 而 .gitignore 又忽略了该文件夹 如果利用 tar.gz 打包则会将那些忽略的文件文件夹一并打包, 可能会造成压缩包极大的臃肿 而又不想仅仅为了打个包就删除整个 build 目录(如重新 build 时间成本太大) 那么就可以使用 bundle 进行打包, 该命令只打包 track 过的文件 并且像 url 那样直接调用 git clone 来重建

bundle 也可以打包指定的区间, 至于提交区间有多种表示方式

使用 GitHub

其他配置

配置 .gitignore 文件

文件 .gitignore 生效后

配置别名

References

子模块

Last updated