Git入门与实践-读书笔记

GitHub 入门与实践 记录

《GitHub 入门与实践》 读书笔记

了解GitHub

Git 和 GitHub 的区别

在Git中,开发者将源代码存入名为“Git仓库”的资料库中,并加以使用。而GitHub则是在网络上提供Git仓库的一项服务。这也就是说Github上公开的软件源代码都是有Git进行管理。

社会化编程

SOCIAL CODING.随着GitHub的出现,让所有人都平等的拥有了更改源代码的权利,软件开发者们才真正意义上拥有了源代码.

GITHUB 特殊技巧

搜索文件

在仓库页面按 ‘t’键,然后输入要找的目录或者文件的部分名称,筛选器会在仓库目录和文件中进行筛选,搜索出要找的文件。这种方式比一级级查看目录和文件要快得多。

查看差别

在github上,直接修改URL就可以让用户以多种形式查看差别。

查看分支之间的差异

https://github.com/rails/rails/compare/4-0-stable...5-0-stable

这样就可以查看两个分支之间的差异了。上面的网页可以看到,两个版本之间提交有上万次,Files changed 有3315….

查看与几天前的差别

https://github.com/rails/rails/compare/master@{7.day.ago}...master

这样就可以查看这段期间内的差别。day 还有其他几种形式。

  • day
  • week
  • month
  • year

查看与指定日期之间的差异

https://github.com/rails/rails/compare/master@{2016-09-01}...master

这样便可以查看与指定日期之间的差别。

由于可以从多种角度查看差别,所以github也称得上是一款优秀的源代码查看器。善于利用上述技巧,能节省不少时间。

GMF 语法特殊用法

GMF github-flavored-markdown.MD语法不做过多介绍,只介绍其中一些特性。

语法高亮

1
2
3
def hello_world
puts 'hello world'
end

这样一来,代码就会被添加语法高亮,变得直观易读。

TaskList 语法

//本月计划的任务
- [ ] 完成ES6语法改造
- [ ] 完成非正常单词改造
- [x]  学完GITHUB特殊技巧
  • [ ] 完成ES6语法改造
  • [ ] 完成非正常单词改造
  • [x] 学完GITHUB特殊技巧

这样一来 ,这段文字就会标记成复选列表的样式。这个复选样式可以直接勾选或者取消。不必打开编辑器重新编辑,非常方便

在评论中应用表情

在评论中输入 “:” 便会启动表情自动补全功能。只需要输入几个与表情相关的字母,系统就会为您筛选自动补全的对象。具体表情见:http://www.emoji-cheat-sheet.com

Issue 技巧

在相关Issue中显示提交信息

在Issue一览表中,可以看到,每个Issue的标题下面都带了诸如 “#21” 的编号。这样只要在提交信息时,带上 “#21” 就可以在Issue中看到该提交信息,使关联的提交一幕了然

Close Issue

在提交信息中以下列任一一种格式描述提交信息,对应的Issure就会被close。

  • fix #21
  • fixes #21
  • fixed #21
  • close #21
  • closes #21
  • closed #21
  • resolve #21
  • resolves #21
  • resolved #21

利用该方式,每次提交并且push后,就不必大费周章到GitHub的Issue中寻找相应的Issue 再手动Close。

Git 操作

Git 基本操作

  • git init ——初始化仓库
  • git status ——查看仓库状态
  • git add ——向暂存区添加文件
  • git commit ——保存仓库的历史记录,.可以将当前暂存区中的文件实际保存到仓库的历史记录中.通过这些记录,我们可以在工作树中复原文件

    • -m参数:参数后为提交信息的概述(单行)
    • 如果想要记述得更加详细,不加-m,执行后编辑器会启动,格式如下

      第一行:用一行文字简述提交的更改内容
      第二行:空行
      第三行以后:记述更改的原因和详细内容
      
  • git log —— 查看提交日志

    • 只显示提交信息的第一行 git log –pretty=short
    • 只显示指定目录/文件的日志 git log README.md
    • 显示文件前后的改动 git log -p README.md
  • git diff —— 查看更改前后的差别

    • 查看工作树和暂存区的差别 git diff
    • 查看工作树和最新提交的差别 git diff HEAD.(不妨养成这样一个好习惯:在执行git commit前,执行git diff HEAD命令,查看本次提交和上次提交的差别,确认后再提交)

其他常用操作

#(项目在github上)直接clone 远程仓库
git clone git@github.com:michaelliao/gitskills.git
#(本地已有项目)上传本地文件到远程仓库
git init
git remote add origin git@xxxx.git
git add .
git commit -m 'something'
git push origin master
git :
#可以丢弃工作区的修改 (commit 之前
git checkout -- file
#把暂存区的修改撤销掉(unstage),重新放回工作区
git reset HEAD file
#从远程仓库更新最新代码
git pull origin master
#清除提交缓存,然后可以重新添加
git rm -r --cached .  /或者指定文件 

#放弃本地所有修改(未track)
git checkout . && git clean -xdf

分支操作

#创建新分支,并且切换到新分支
git checkout -b dev
# 查看当前分支
git branch
# 提交到当前分支
git push origin dev
# 合并到主分支,先切换到 主分支,再merge
git checkout master
git merge dev
#合并后,还需要再push一次
git push origin master
#删除分支
git branch -d dev
git push origin :dev

# 查看所有分支
git branch -a
# git fetch
git fetch

# git 获取远程分支,checkout到本地
# git checkout -b local_branch origin/remote_branch:把远程remote_branch 映射到本地 local_branch
git checkout -b dev origin/dev

# 删除远程分支
# 冒号前面的空格不能少,原理是把一个空分支push到server上,相当于删除该分支。
git push origin :branch-name

tag 操作

git tag -a v1.0 -m 'some message'
git show v1.0
git push origin v1.0
# 删除 tag
git tag
git tag -d v1.1
git push origin --delete tag v1.1

Git: 分支操作

  • git branch —— 显示分支一览表
  • git checkout -b —— 创建、切换分支

    • 创建分支,并切换到分支,并提交

      $ git checkout -b feature-A
      Switched to a new branch 'feature-A' 
      //实际上等同于下面两条命令
      $ git branch feature-A
      $ git checkout feature-A
      
    • 切回到master, git checkout master

    • 切回到上一个分支,git checkout - , 用”-“ 可以代替分支名
  • 特性分支:是集中实现单一特性(主题),初次之外不进行任何作业的分支。

  • 主干分支:可以发布软件的稳定分支。有时可以用标签Tag等创建版本信息,同时管理多个版本的发布。
  • git merge ——合并分支

    • 假设 feature-A 已经开发完,先需要将它合并到master。

      $ git checkout master
      $ git merge --no--ff feature-A
      // 为了在历史记录中明确记录本次分支合并,我们需要创建合并提交。因此需要加上 --no--ff 参数
      
  • git log –graph —— 以图表的形式查看分支。*该命令可以用图表形式输出提交日志,非常直观

更改提交的操作

  • git reset ——回溯历史版本

    • 要让仓库的HEAD、暂存区、当前工作树回溯到指定状态,需要用到git reset –head 命令。只需要提供hash值,就可以完全恢复至该时间点的状态
    • git log 只能查看当前状态为终点的历史日志。用git reflog 可以查看当前仓库的操作日志。通过log查找hash值,通过reset –hard 命令恢复到回溯历史前的状态
  • 消除冲突

    • 解决冲突后,执行git add 和git commit命令

      <<<<<<< HEAD
         -feature-A
      =======
         -fix-B
      >>>>>>> fix-B
      
  • git commit –amend ——修改提交的comment (上一条),执行命令后,会启动编辑器。执行 git log –graph 可以查看是否修改成功。

  • git rebase -i —— 压缩历史日志。

    • git rebase -i HEAD~2 : 可以选定当前分支中包含HEAD(最新提交)在内的两个最新历史记录对象,并在编辑器中打开

      pick 7a33333 Add feature-C
      pick 6f11111 Fix typo
      
      #p,pick = use commit
      #r,reword = use commit,but edit the commit message
      #e,edit = use commit,but stop for emending
      #s,squash = use commit, but meld into previous commit
      #f,fixup = like 'squash',but discard this commit`s log message
      #x,exec = run command (the rest of the line) using shell
      
      //将6f11111 Fix typo的历史记录,压缩到7a33333的Add feature-C里。将pick删除,改写为fixup
      pick 7a33333 Add feature-C
      fixup 6f11111 Fix typo
      

远程仓库操作

  • git remote add ——添加远程仓库

    $ git remote add origin git@github.com:github-book/git-tutorial.git
    
  • git push —— 推送至远程仓库

  • git clone —— 获取远程仓库

    • 执行clone 命令后,默认处于master分支
    • git check -b feature -D origin/feature-D
  • git pull —— 获取最新的远程仓库分支

如果两人同时修改了统一部分源代码,push时就很容易发生冲突。所以多名开发者在同一个分支中进行作业时,为减少冲突情况发生,建议频繁地进行push和pull操作

GitHub 的其他功能

GitHub Pages

Github pages 主要用于在Github上托管静态HTML,以便发布项目的Web页。

由于可以绑定独立的域名,人们也经常利用结合这个功能的Octopress 来搭建博客

Github Jobs

面向全世界招聘程序员的职位公告板。Jobs

Github Enterprise

企业版

Github API

GitHub 面向开发者公开了API。 具体见 https://developer.github.com

Pull Request

按部就班地创建GitHub账号并公开自己的源码并不是什么难事。Pull Request 是社会化编程的象征,可以说给开源开发世界带来了一场革命。不会用这个功能,就等于不会用GitHub。。。(作者吹得有点过。。)

Pull Request 是GitHub的核心功能

Conversation

(以下技巧同样可以应用在其他评论中,如Issue)

在评论中应用表情

(同样应用在其他评论中,如Issue)在评论中输入 “:” 便会启动表情自动补全功能。只需要输入几个与表情相关的字母,系统就会为您筛选自动补全的对象。具体表情见:http://www.emoji-cheat-sheet.com

引用评论

只要选中需要引用的语句,然后按“R键”便会自动以引用的形式添加到评论栏,这样一来就可以轻松便捷地引用评论了

让Pull Request 更加有效的方法

在开发过程中发送Pull Request进行讨论

避免一个功能在开发完成后才收到来自设计或者实现方面的指正,导致代码需要大幅更改或者重新实现

明确标出 “正在开发过程中”

为了防止开发到一半的Pull Request 被合并,一般在标题前加上 “[WIP]” 字样,WIP 是 Work In Progress的简称

不进行Fork 直接从分支发送Pull Request

一般来说,在Github上修改对方的代码时,需要先将仓库Fork到本地,然后再修改代码,发送Pull Request。

但是,如果用户对该仓库有编辑权限,则可以直接创建分支,从分支发送 Pull Request

采纳Pull Request

接收到Pull Request 后

#介绍基于Git 两种协作开发模式,GitHub Flow & Git Flow

一 GitHub Flow

GitHub Flow —— 以部署为中心的开发模式,通过简单的功能和规则,持续高速 安全地进行部署。在实际开发中往往一天之内会实施几十次部署,而支撑这一切的,就是足够简单的开发流程以及完全的自动化。

git-flow-feature

GitHub Flow 特点

  1. 令master 分支时常保持可以部署的状态
  2. 进行新的作业时要从master 分支创建新的分支,新分支名称要具有描述性
  3. 2新建的本地仓库分支中进行提交
  4. 在Github 端仓库创建同名分支,定期push
  5. 需要帮助、反馈,或者branch已经准备merging时,创建Pull Request,以Pull Request 进行交流
  6. 让其他开发者进行审查,确认作业完成后与master分支进行合并(合并的代码一定要测试
  7. 与master分支合并后,立刻部署

使用Github Flow 的前提条件

  • 团队规模最好控制在15-20人之内,具体见 how-github-works
  • 部署作业完全自动化。必须自动化,一天之类需要多次部署
    • 使用部署工具(Capistrano,Mina,Fabric,Webistrano,Strano等),让部署时所需的一系列流程自动化。
    • 通过Web界面进行部署,Capistrano 等部署工具需要命令执行操作,开发者以外的人很难实施部署
    • 导入开发时注意事项:随着团队人数的增多及成熟度的提高,开发速度会越来越快。往往一个部署尚未完成,另一名开发者就已经处理完下一个pull request,开始实施下一个部署。在这种情况下,一旦正式环境出现问题,很难分辨哪个部署造成了影响。为了应对该情况,建议在部署实施过程中通过工具加锁。
    • Git Hook 自动部署
  • 重视测试
    • 让测试自动化
    • 编写测试代码,通过全部测试
    • 维护测试代码

git-flow-feature

二 Git Flow

荷兰程序员 Vincent Driessen 曾发表了一篇博客,让一个分支策略广为人知。具体流程见下图(引用该博客的一幅图片)

git-model

这一流程最大的亮点是考虑了紧急Bug的应对措施,整个流程显得过于复杂,所以在实施该方案前,需要对整个开发流程进行系统的学习。也需要借助Git flow 等工具的辅助。

下面根据上图,按块说明:

master 分支和 develop分支

在Git Flow 中,这两个分支至关重要,它们会贯彻整个流程始终,绝对不会被删除。

master 分支

master 分支时常保持着软件可以正常运行的状态。由于要维护这一状态,所以不允许开发者直接对master 分支的代码进行修改和提交。

其他分支的开发工作进展到可以发布的程度后,将会与master分支进行合并,并且这一合并只在发布成品时进行。发布时将会附加版本编号的Git标签。

develop分支

develop分支是开发过程中代码中心分支。与master 分支一样,这个分支也不允许开发者直接进行修改和提交。

程序员要以develop分支为起点新建feature 分支,在feature 分支中进行新功能的开发或者代码的修正。也就是说develop分支维系着开发过程中的最新代码,以便程序员创建feature分支进行自己的工作。

在feature 中工作

feature 分支以develop分支为起点,是开发者直接更改代码发送提交的分支。开发流程:

  1. 从develop分支创建feature分支
  2. 从feature分支中实现目标功能
  3. 通过Github 向develop发送pull request
  4. 接受其他开发者审核后,将Pull Request合并至develop分支

具体指令:

$ git checkout develop
$ git pull
$ git flow feature start add-user //add branch feature/add-user
$ git branch
// feature/add user  start commit commit ....
$ git push orgin feature/add-user
//到github 上去代码审查,切到develop分支,进行pull request 
$ git checkout develop
$ git pull // 当feature/add-user 合并到 develop后,本地develop 需要更新到最新状态

注意,默认状态是pull request 到master。这时需要手动切换到develop分支,再进行pull Request 操作。
如果采用该开发策略,那么可以在setting 中 Option 中,修改Default Branch 为 develop ,这样就省去了手动修改的麻烦。

与develop分支合并后,已经完成工作的feature分支可以在适当的时机删除

git-flow-feature

更新本地的develop分支

我们发送的pull request 在github 端与develop 合并后,为了让其反应到本地的develop分支中,我们需要进行以下操作:

  • 切换到develop分支
  • 执行git pull (fetch & merge)

每当需要从develop分支创建feature等分支时,记得一定要先执行上述操作,保证develop分支处于最新状态。

release分支

创建 release分支 ,在这个分支,我们只处理与发布前准备相关的提交,比如版本编号变更的元数据的添加工作。如果软件部署到预演环境后测试出bug,相关修正也要提交到这个分支。

注意:该分支绝对不能包含需求变更或者功能变更等重大修正。这一阶段的提交数应该限制到最低。

$ git checkout develop
$ git pull
$ git flow release start '1.0.0'

当所有修正处理完后,我们结束这分支

$ git flow release finish '1.0.0'
//期间会需要填写 提交信息、这个版本的提交信息、合并的提交信息。无特殊情况,一般默认。

全部结束后,会显示如下

$ git flow release finish '1.0.0'
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Merge made by the 'recursive' strategy.
 README.md | 2 ++
 1 file changed, 2 insertions(+)
Switched to branch 'develop'
Your branch is up-to-date with 'origin/develop'.
Already up-to-date!
Merge made by the 'recursive' strategy.
Deleted branch release/1.0.0 (was d3f54a0).

Summary of actions:
- Release branch 'release/1.0.0' has been merged into 'master'
- The release was tagged '1.0.0'
- Release tag '1.0.0' has been back-merged into 'develop'
- Release branch 'release/1.0.0' has been locally deleted
- You are now on branch 'develop'

查看版本tag

通过前面一系列的操作,我们创建了与发布版本号相同的Git标签

$ git tag
1.0.0

更新到远程仓库

对此,我们对多个分支进行了修改,所以需要利用push操作将修改更新到Github端的远程仓库。先从develop开始

$ git push origin develop

然后是master

$ git checkout master
$ git push origin master

再push 标签信息

$ git push --tags

这样版本号 1.0.0 的标签信息就已经push 完成

在hotfix 分支下进行工作

下述情况需要创建 hotfix 分支

  • release 版本中发现了bug 或者漏洞
  • develop 分支正在开发新功能,无法面向用户进行发布
  • 漏洞需要及早处理,无法等到下一次版本发布

假设修复BUG 后的版本至 1.0.1

$ git fetch origin

现在以1.0.0的标签信息为起点,创建名为1.0.1 的hotfix分支。

$ git flow hotfix start '1.0.1' '1.0.0'

修复工作结束后,将hotfix 分支push 到github端的远程仓库,并向master分支发起Pull Request

$ git push origin hotfix/1.0.1

git-flow-feature

创建标签和进行发布

在Github项目主页,点击release ,为本次hotfix 创建1.0.1标签。点击 Draft a new release 按钮,输入相关标签信息,在Target中指定master分支(master分支已经合并了hotfix1.0.1的修改)。然后填写相关信息,点击Publish release 进行发布

1.0.1发布后,之前发布的成品也就完成了生命周期

$ git fetch origin

从 hotfix 分支合并到develop 分支

登录到Github,从hotfix1.0.1分支向develop分支发送Pull Request即可。审查后便会被合并到develop分支

Git Flow 的小结

建议把开发流程图放大贴在墙上,这样能够有效帮助团队成员理解流程内容

版本号的分配规则 x.y.z

x: 在重大功能变更,或者版本不向下兼容+1,此时y z归零
y: 在添加新功能或者删除已有功能+1 此时z归零
z: 只在进行内部修改后+1.

Gist

Gist 是一款简单的Web应用程序,常用来共享示例代码和错误信息。

坚持原创技术分享,您的支持将鼓励我继续创作!
分享