Git 入门实战
关于我



n   ⺩王燊 aka icyleaf
n   http://github.com/icyleaf
个人 SCM 使用经历

n   2008 文件打包备份 (个人解决方案)
n   2008 1-2 个月 CVS (同事解决方案)
n   2008 - 2009 SVN(源于 Wordpress)
n   2009 - 至今 Git (源于 Kohana PHP 3.0)
什么是
版本控制
本地
集中式
分布式
为什么
 使用
 Git
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 内核代码
git 与 svn
n   git 是分布式,svn是集中式
n   git 速度快,svn 慢的一塌糊涂
n   git 把内容按元数据方式存储,svn 是按文件
n   git branch 灵活且强大,svn 仅仅是文件复制管理
n   git 有无尽的后悔药,svn 的恢复显得有些苍白
体积⽐比较




Clone (Checkout) 速度
SVN




Git
快速入门
平台支持

n   Linux
n   Mac OS X
n   Windows (Msysgit on Google Code)
CLI 才是王道

n   建议使用 Unix/Linux 系统
n   GUI 只包含基本功能
n   CLI 让你感受到 git 的强大
初次配置

 git config --global user.name “icyleaf”

 git config --global user.email “icyleaf.cn@gmail.com”




Windows
git config --global core.filemode false

git config --global core.autocrlf true
创建仓库

# 本地创建仓库

git init

# 创建纯净的仓库(多适⽤用于服务器端)

git init --bare --shared
克隆仓库
# 本地⽂文件路径
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://git@github.com:progit/progit.git
git clone git@github.com:progit/progit.git
工作流
添加&提交
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
查看历史
git log

# 查看最近 3 次提交的详细修改内容

git log -p -3

# 查看 icyleaf ⽤用户最近⼀一个星期提交信息

git log --author icyleaf --since=‘one week ago’

# ⽤用简单图形查看分⽀支提交的情况

git log --graph --oneline
恢复
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
回滚历史

# 回滚到最近历史提交的倒数第⼆二个 commit

git reset --soft HEAD~2

# 回滚到某个特性的 commit

git reset --hard {hash}
分支
# 列出当前所有本地分⽀支
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
本地远程仓库
# 查看本地远程仓库

git removte -v

# 添加本地远程仓库

git remote add upstream http://github.com/icyleaf/repo.git

# 改名本地远程仓库

git remote rename upstream icyleaf

# 删除本地远程仓库

git remote rm icyleaf
推送至服务器
# 推送本地 master 分⽀支到远程 origin 上⾯面

git push -u origin master



           -u 的作用是保持分支合并的图形完整
           性,如果不带的话历史只有一条主线



# 删除远程 origin 上⾯面提交的临时分⽀支:issue3

git push origin :issue3



           git push [远程名] [本地分⽀支]:[远程分⽀支]
跟踪分支(拉取代码)
 # 更新远程仓库的最新代码索引

 git fetch origin

 git merge origin/master



 # 直接更新病合并最新的分⽀支代码

 git pull --no-ff orign master




                默认 git pull 可以等同于上面。其实配置文件帮你设置。
合并代码
git checkout -b hotfix

# 开始修复代码

git checkout master

# 合并 hotfix 的代码

git merge hotfix

# 如果没有冲突⽂文件会以 Fast forward 的⽅方式顺利合并

# 如果发⽣生冲突,使⽤用 git status 查看冲突的⽂文件(类似 SVN 状况)

# 解决后,使⽤用 git add 标记已完成,并 git commit 提交冲突⽂文件
衍合(变基)分支
# 假如想修改最近三个的 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
标签
# 查看当前所有标签

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
services

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



    我们禁⽌止提交不能编译通过(未完成功能代码)的

    代码,尽量不提交缺陷代码。对于很复杂的模块,

    有⼈人⼏几乎⼀一个月都没提交过⼀一次。但⼏几经修改的代

    码其实从来没有作版本控制。


    怎样保证提交的完整性和可运⾏行性?
2




    在没有⺴⽹网络的情况下,突然发现 bugs 或者被告知

    需要完成紧急项⺫⽬目的开发。


    但是没有⺴⽹网络(有本地开发环境),怎么办?
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

                               本地多次提交完成功能,
                               最后统一提交到服务器。
3




    某⼈人写了⼀一个模块,总是有 bug 没有修改完,⽽而不

    敢提交。这个时候,另⼀一个⼈人希望协助他找问题,

    却没有合适的途径提交那段完成了⼀一半的模块。


    怎么解决多模块同步开发的问题?
分⽀支⼯工作流

•master
•develop
•hotfixes




via (a successful git branching model)
4




    我的项⺫⽬目中有⽤用到⼀一些 Github 上开源的项⺫⽬目,开

    源项⺫⽬目避免不了会有缺陷和新特更新。


    怎么保证多项⺫⽬目共存性和同步性?
子模块
# 假设有⼀一个 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
5



    随着不断的 commit,突然发现有⼀一天,历史

    commit 有些⽂文件包含私密数据,在 reset 的时

    候,⼀一不⼩小⼼心把另外重要数据抹掉了,再看 log 的

    时候发现最新的⼏几个 commit 不⻅见了!!

    难道只能通宵加班补代码了?!
最后的后悔药
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 会
                              做垃圾处理掉
6




    这个话题都讲那么⻓长时间了,我⼼心⾥里痒痒的很,可

    是...可是...我们公司⽤用的还是 svn 啊!啊!!

    啊!!!!!!!!


    哈,git 其实还拥有⼀一种秘密武器:git-svn
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
Subgit




http://subgit.com/
7



    我们公司开发环境为了⽅方便开发测试和部署,特意

    部署了两套 svn:⼀一个专⻔门提交到测试机器,另外

    ⼀一个专⻔门提及到产品机器上⾯面部署。

    如果使⽤用 git 的话,怎么能把两者代码完美且快速

    的融合,推送到产品机器发布?
继续利用分支特性
创建两个 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
资源
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/
Q&A
Thanks

Git 入门实战

  • 1.
  • 2.
    关于我 n ⺩王燊 aka icyleaf n http://github.com/icyleaf
  • 4.
    个人 SCM 使用经历 n 2008 文件打包备份 (个人解决方案) n 2008 1-2 个月 CVS (同事解决方案) n 2008 - 2009 SVN(源于 Wordpress) n 2009 - 至今 Git (源于 Kohana PHP 3.0)
  • 5.
  • 6.
  • 7.
  • 8.
  • 10.
  • 11.
    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 内核代码
  • 12.
    git 与 svn n git 是分布式,svn是集中式 n git 速度快,svn 慢的一塌糊涂 n git 把内容按元数据方式存储,svn 是按文件 n git branch 灵活且强大,svn 仅仅是文件复制管理 n git 有无尽的后悔药,svn 的恢复显得有些苍白
  • 13.
  • 14.
  • 15.
  • 16.
    平台支持 n Linux n Mac OS X n Windows (Msysgit on Google Code)
  • 17.
    CLI 才是王道 n 建议使用 Unix/Linux 系统 n GUI 只包含基本功能 n CLI 让你感受到 git 的强大
  • 18.
    初次配置 git config--global user.name “icyleaf” git config --global user.email “icyleaf.cn@gmail.com” Windows git config --global core.filemode false git config --global core.autocrlf true
  • 19.
    创建仓库 # 本地创建仓库 git init #创建纯净的仓库(多适⽤用于服务器端) git init --bare --shared
  • 20.
    克隆仓库 # 本地⽂文件路径 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://git@github.com:progit/progit.git git clone git@github.com:progit/progit.git
  • 21.
  • 23.
    添加&提交 touch README git addREADME git commit -m “add README” touch LICENSE git status echo “Hello, World” > README git commit -am “updated README” git status
  • 25.
    查看历史 git log # 查看最近3 次提交的详细修改内容 git log -p -3 # 查看 icyleaf ⽤用户最近⼀一个星期提交信息 git log --author icyleaf --since=‘one week ago’ # ⽤用简单图形查看分⽀支提交的情况 git log --graph --oneline
  • 26.
    恢复 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
  • 28.
    回滚历史 # 回滚到最近历史提交的倒数第⼆二个 commit gitreset --soft HEAD~2 # 回滚到某个特性的 commit git reset --hard {hash}
  • 30.
    分支 # 列出当前所有本地分⽀支 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
  • 32.
    本地远程仓库 # 查看本地远程仓库 git removte-v # 添加本地远程仓库 git remote add upstream http://github.com/icyleaf/repo.git # 改名本地远程仓库 git remote rename upstream icyleaf # 删除本地远程仓库 git remote rm icyleaf
  • 33.
    推送至服务器 # 推送本地 master分⽀支到远程 origin 上⾯面 git push -u origin master -u 的作用是保持分支合并的图形完整 性,如果不带的话历史只有一条主线 # 删除远程 origin 上⾯面提交的临时分⽀支:issue3 git push origin :issue3 git push [远程名] [本地分⽀支]:[远程分⽀支]
  • 34.
    跟踪分支(拉取代码) # 更新远程仓库的最新代码索引 git fetch origin git merge origin/master # 直接更新病合并最新的分⽀支代码 git pull --no-ff orign master 默认 git pull 可以等同于上面。其实配置文件帮你设置。
  • 35.
    合并代码 git checkout -bhotfix # 开始修复代码 git checkout master # 合并 hotfix 的代码 git merge hotfix # 如果没有冲突⽂文件会以 Fast forward 的⽅方式顺利合并 # 如果发⽣生冲突,使⽤用 git status 查看冲突的⽂文件(类似 SVN 状况) # 解决后,使⽤用 git add 标记已完成,并 git commit 提交冲突⽂文件
  • 38.
    衍合(变基)分支 # 假如想修改最近三个的 commit gitrebase -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
  • 40.
    标签 # 查看当前所有标签 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
  • 41.
    services n Github (git) (public free) n Bitbucket (hg/git) (public & private all free) n Google Code (svn/hg/git) (public only)
  • 42.
  • 43.
    1 我们禁⽌止提交不能编译通过(未完成功能代码)的 代码,尽量不提交缺陷代码。对于很复杂的模块, 有⼈人⼏几乎⼀一个月都没提交过⼀一次。但⼏几经修改的代 码其实从来没有作版本控制。 怎样保证提交的完整性和可运⾏行性?
  • 44.
    2 在没有⺴⽹网络的情况下,突然发现 bugs 或者被告知 需要完成紧急项⺫⽬目的开发。 但是没有⺴⽹网络(有本地开发环境),怎么办?
  • 46.
    commit & push gitadd 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 本地多次提交完成功能, 最后统一提交到服务器。
  • 47.
    3 某⼈人写了⼀一个模块,总是有 bug 没有修改完,⽽而不 敢提交。这个时候,另⼀一个⼈人希望协助他找问题, 却没有合适的途径提交那段完成了⼀一半的模块。 怎么解决多模块同步开发的问题?
  • 48.
  • 49.
    4 我的项⺫⽬目中有⽤用到⼀一些 Github 上开源的项⺫⽬目,开 源项⺫⽬目避免不了会有缺陷和新特更新。 怎么保证多项⺫⽬目共存性和同步性?
  • 50.
    子模块 # 假设有⼀一个 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
  • 51.
    5 随着不断的 commit,突然发现有⼀一天,历史 commit 有些⽂文件包含私密数据,在 reset 的时 候,⼀一不⼩小⼼心把另外重要数据抹掉了,再看 log 的 时候发现最新的⼏几个 commit 不⻅见了!! 难道只能通宵加班补代码了?!
  • 52.
    最后的后悔药 git reset --hard3d2x9 # 发现回滚错了,⽽而之前的 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 会 做垃圾处理掉
  • 53.
    6 这个话题都讲那么⻓长时间了,我⼼心⾥里痒痒的很,可 是...可是...我们公司⽤用的还是 svn 啊!啊!! 啊!!!!!!!! 哈,git 其实还拥有⼀一种秘密武器:git-svn
  • 54.
    git-svn # Clone 指定⺫⽬目录下,相依起始版本号的代码 gitsvn clone https://intra.leju.com/svn/mobile -s -r524:HEAD # 其他操作(如,add,commit,log 等)全部使⽤用 git 本⾝身的命令 # 提交代码到 svn 服务器 git svn dcommit # 从 svn 服务器获取最新代码 git svn rebase
  • 55.
  • 56.
    7 我们公司开发环境为了⽅方便开发测试和部署,特意 部署了两套 svn:⼀一个专⻔门提交到测试机器,另外 ⼀一个专⻔门提及到产品机器上⾯面部署。 如果使⽤用 git 的话,怎么能把两者代码完美且快速 的融合,推送到产品机器发布?
  • 57.
    继续利用分支特性 创建两个 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
  • 58.
    资源 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/
  • 59.
  • 60.