Slide 1

Slide 1 text

Git 入门实战

Slide 2

Slide 2 text

ܱႿ໡ n ⺩王燊 aka icyleaf n http://github.com/icyleaf

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

个人 SCM 使用经历 n 2008 文件打包备份 (个人解决方案) n 2008 1-2 个月 CVS (同事解决方案) n 2008 - 2009 SVN (源于 Wordpress ) n 2009 - 至今 Git (源于 Kohana PHP 3.0 )

Slide 5

Slide 5 text

什么是 版本控制

Slide 6

Slide 6 text

本地

Slide 7

Slide 7 text

集中式

Slide 8

Slide 8 text

分布式

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

为什么 使用 Git

Slide 11

Slide 11 text

Linus Torvalds n 05.4.3 Git 项目启动 n 05.4.6 项目第一版发布 n 05.4.7 Git 作为自身的版本控制工具 n 05.4.18 发布第一个多分支合并 n 05.4.29 Git 性能已经达到预期 n 05.6.16 Git 正式维护 Linux 内核代码

Slide 12

Slide 12 text

git 与 svn n git 是分布式, svn 是集中式 n git 速度快, svn 慢的一塌糊涂 n git 把内容按元数据方式存储, svn 是按文件 n git branch 灵活且强大, svn 仅仅是文件复制管理 n git 有无尽的后悔药, svn 的恢复显得有些苍白

Slide 13

Slide 13 text

体积⽐比较 Clone (Checkout) 速度

Slide 14

Slide 14 text

SVN Git

Slide 15

Slide 15 text

快速入门

Slide 16

Slide 16 text

平台支持 n Linux n Mac OS X n Windows (Msysgit on Google Code)

Slide 17

Slide 17 text

CLI 才是王道 n 建议使用 Unix/Linux 系统 n GUI 只包含基本功能 n CLI 让你感受到 git 的强大

Slide 18

Slide 18 text

初次配置 git config --global user.name “icyleaf” git config --global user.email “[email protected]” git config --global core.filemode false git config --global core.autocrlf true Windows

Slide 19

Slide 19 text

创建仓库 # 本地创建仓库 git init # 创建纯净的仓库(多适⽤用于服务器端) git init --bare --shared

Slide 20

Slide 20 text

克隆仓库 # 本地⽂文件路径 git clone /opt/git/project.git # ⽂文件协议 git clone file://opt/git/project.git # HTTP 协议 git clone https://github.com/progit/progit.git # SSH 协议 git clone ssh://[email protected]:progit/progit.git git clone [email protected]:progit/progit.git

Slide 21

Slide 21 text

工作流

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

添加 & 提交 touch README git add README git commit -m “add README” touch LICENSE git status echo “Hello, World” > README git commit -am “updated README” git status

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

查看历史 git log # 查看最近 3 次提交的详细修改内容 git log -p -3 # 查看 icyleaf ⽤用户最近⼀一个星期提交信息 git log --author icyleaf --since=‘one week ago’ # ⽤用简单图形查看分⽀支提交的情况 git log --graph --oneline

Slide 26

Slide 26 text

恢复 echo “Hellp, icyleaf” > README git checkout -- README echo “Hello, icyleaf” > README git add README git reset -- README echo “Hello, Mr. icyleaf” > README git commit -am ‘Modified README’ git commit --amend

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

回滚历史 # 回滚到最近历史提交的倒数第⼆二个 commit git reset --soft HEAD~2 # 回滚到某个特性的 commit git reset --hard {hash}

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

分支 # 列出当前所有本地分⽀支 git branch # 新建⼀一个名为 develop 的分⽀支并切换到它 git branch develop git checkout master # 下⾯面⼀一⾏行命令等同于上⾯面两⾏行(快速⾼高效,推荐!) git checkout -b develop # 改名分⽀支 git branch -m develop 2.0/develop # 删除分⽀支 git branch -d 2.0/develop

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

本地远程仓库 # 查看本地远程仓库 git removte -v # 添加本地远程仓库 git remote add upstream http://github.com/icyleaf/repo.git # 改名本地远程仓库 git remote rename upstream icyleaf # 删除本地远程仓库 git remote rm icyleaf

Slide 33

Slide 33 text

推送至服务器 # 推送本地 master 分⽀支到远程 origin 上⾯面 git push -u origin master # 删除远程 origin 上⾯面提交的临时分⽀支:issue3 git push origin :issue3 git push [远程名] [本地分⽀支]:[远程分⽀支] -u 的作用是让 git 知道默认 push 的 remote 和 branch ,方便 默认 pull 。

Slide 34

Slide 34 text

跟踪分支(拉取代码) # 更新远程仓库的最新代码索引 git fetch origin git merge origin/master # 直接更新病合并最新的分⽀支代码 git pull orign master 默认可以使⽤用 git pull 代替。

Slide 35

Slide 35 text

合并代码 git checkout -b hotfix # 开始修复代码 git checkout master # 合并 hotfix 的代码 git merge --no-ff hotfix # 如果没有冲突⽂文件会以 Fast forward 的⽅方式顺利合并(--no-ff 的 作⽤用是保证合并是有多分⽀支合并的记录,默认是 --ff,直接把 commit 合并到⼀一条主线上) # 如果发⽣生冲突,使⽤用 git status 查看冲突的⽂文件(类似 SVN 状况) # 解决后,使⽤用 git add 标记已完成,并 git commit 提交冲突⽂文件

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

衍合(变基)分支 # 假如想修改最近三个的 commit git rebase -i HEAD~3 # 回滚到某个特性的 commit pick f7f3f6d changed my name a bit edit 310154e updated README formatting and added blame pick a5f4a0d added cat-file # Rebase 710f0f8..a5f4a0d onto 710f0f8 # # Commands: # p, pick = use commit # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. # 对于 edit 的 commit 进⾏行任意操作 # 修改完毕(git commit)之后没问题了继续衍合当前 commit git rebase --continue # 如果当前 edit 不需要编辑了可以跳过 git rebase --skip

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

标签 # 查看当前所有标签 git tag # 标记当前分⽀支为 v1.0 版本作为归档 git tag -a v1.0 # 添加带备注的标签 git tag -a v1.2.1225 -m ‘圣诞节特别版本’ # 把历史特定 commit 标记标签 git tag -a v1.1 1d2x33 # 查找 v1.0 版本下有多少标记的⼩小版本 git tag -l ‘v1.*’ # 分享标签 git push origin v1.0

Slide 41

Slide 41 text

services n Github (git) (public free) n Bitbucket (hg/git) (public & private all free) n Google Code (svn/hg/git) (public only)

Slide 42

Slide 42 text

实战

Slide 43

Slide 43 text

我们禁⽌止提交不能编译通过(未完成功能代码)的 代码,尽量不提交缺陷代码。对于很复杂的模块, 有⼈人⼏几乎⼀一个月都没提交过⼀一次。但⼏几经修改的代 码其实从来没有作版本控制。 1 怎样保证提交的完整性和可运⾏行性?

Slide 44

Slide 44 text

在没有⺴⽹网络的情况下,突然发现 bugs 或者被告知 需要完成紧急项⺫⽬目的开发。 2 但是没有⺴⽹网络(有本地开发环境),怎么办?

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

commit & push git add README git commit -m “first commit” echo “hello world” > README git commit -am “updated README” echo “missing content” >> README git commit -am “completed README” git push origin master 本地多次提交完成功能, 最后统一提交到服务器。

Slide 47

Slide 47 text

某⼈人写了⼀一个模块,总是有 bug 没有修改完,⽽而不 敢提交。这个时候,另⼀一个⼈人希望协助他找问题, 却没有合适的途径提交那段完成了⼀一半的模块。 3 怎么解决多模块同步开发的问题?

Slide 48

Slide 48 text

via (a successful git branching model) 分⽀支⼯工作流 •master •develop •hotfixes

Slide 49

Slide 49 text

我的项⺫⽬目中有⽤用到⼀一些 Github 上开源的项⺫⽬目,开 源项⺫⽬目避免不了会有缺陷和新特更新。 4 怎么保证多项⺫⽬目共存性和同步性?

Slide 50

Slide 50 text

子模块 # 假设有⼀一个 blog 的项⺫⽬目,所有外部模块都放在 vendor 下⾯面。 # ⾸首先添加⼀一个 twig 模板引擎的⼦子模块 git submodule add https://github.com/fabpot/Twig.git vendor/twig # 添加了那么多⼦子模块,我如何全部更新呢? git submodule foreach git pull # clone 别⼈人带⼦子模块的,我怎么获取他们的代码呢? git submodule init && git submodule update git submodule update --init # 我怎么知道⼀一个项⺫⽬目都有哪些⼦子模块? cat .gitmodules

Slide 51

Slide 51 text

随着不断的 commit,突然发现有⼀一天,历史 commit 有些⽂文件包含私密数据,在 reset 的时 候,⼀一不⼩小⼼心把另外重要数据抹掉了,再看 log 的 时候发现最新的⼏几个 commit 不⻅见了!! 5 难道只能通宵加班补代码了?!

Slide 52

Slide 52 text

最后的后悔药 git reset --hard 3d2x9 # 发现回滚错了,⽽而之前的 HEAD 已经没有了!怎么办! git reflog b8981f0 HEAD@{0}: reset: moving to b8981f0 3e15a82 HEAD@{1}: commit: Modified README 07e0183 HEAD@{2}: commit (initial): init git reset --hard 3e15a82 30 天内有效,否则 git 会 做垃圾处理掉

Slide 53

Slide 53 text

这个话题都讲那么⻓长时间了,我⼼心⾥里痒痒的很,可 是...可是...我们公司⽤用的还是 svn 啊!啊!! 啊!!!!!!!! 6 哈,git 其实还拥有⼀一种秘密武器:git-svn

Slide 54

Slide 54 text

git-svn # Clone 指定⺫⽬目录下,相依起始版本号的代码 git svn clone https://intra.leju.com/svn/mobile -s -r524:HEAD # 其他操作(如,add,commit,log 等)全部使⽤用 git 本⾝身的命令 # 提交代码到 svn 服务器 git svn dcommit # 从 svn 服务器获取最新代码 git svn rebase

Slide 55

Slide 55 text

Subgit http://subgit.com/

Slide 56

Slide 56 text

我们公司开发环境为了⽅方便开发测试和部署,特意 部署了两套 svn:⼀一个专⻔门提交到测试机器,另外 ⼀一个专⻔门提及到产品机器上⾯面部署。 如果使⽤用 git 的话,怎么能把两者代码完美且快速 的融合,推送到产品机器发布? 7

Slide 57

Slide 57 text

继续利用分支特性 创建两个 remote(production)/test 和两个 branch(master/ develop) git remote add production http://pro.xxx.com/pro.git git remote add test http://test.xxx.com/pro.git 根据分⽀支 push 到不同的 remote git push test develop git fetch production git merge production/master master (develop)$ git merge master 若有冲突合并之后在测试⽆无误,没问题了合并到 master 推送到产品机器 (master)$ git merge devlop git push production master

Slide 58

Slide 58 text

资源 n http://git-scm.com n https://help.github.com n https://github.com/schacon/whygitisbetter n https://github.com/progit n http://gitready.com n http://gitref.org/

Slide 59

Slide 59 text

Q&A

Slide 60

Slide 60 text

Thanks