Git和Gihub入门

12. Git和Gihub入门

简介

Git是一个快速、可扩展的分布式版本控制系统。所谓版本控制系统 (VersionControl System),从狭义上来说,它是软件项目开发过程中用于储存我们所写的代码所有修订版本的软件,但事实上我们可以将任何对项目有帮助的文档交付版本控制系统进行管理。

2005 年,Torvalds 开 始 着 手 开 发 Git 是 为 了 作 为 一 种 过 渡 方 案 来 替 代BitKeeper,后者之前一直是 Linux 内核开发人员在使用的版本控制工具。Git 的开发是为了辅助 Linux 内核开发的过程,但是现在很多其他自由软件项目中也使用了 Git 实现代码版本管理,譬如,X.org 项目、许多 Freedesktop.org 的项目、Ruby 项目等。

使用Git管理个人文档

Git可以保存任何文档,但是最善于保存文本文档,因为它本来就是为解决软件源代码(也是一种文本文档)版本管理问题而开发的。因此,愈是修改较为频繁的文档,愈是有必要将其纳入 Git 的管理之下。

安装与设置git

  • Linux:只要用yum,apt-get等安装即可,或是下载之后编译安装。
  • Mac OS X:从这里下载并安装。
  • Windows:先安装putty,然后从这里下载并安装。

建立项目仓库

首先要基于现有的文档建立项目仓库,下面以一个项目源码的版本管理为例,假如一个项目在~/dida中,首先初始化Git仓库:

$cd ~/dida
$git init

回应:

Initialized empty Git repository in $PROJECT/.git/

~/dida目录下创建了一个 .git 隐藏目录,它就是所谓的 Git 仓库,不过现在它还是空的。另外 ~/dida目录也不再是普通的文档目录了,今后我们将其称为工作树。

下面把一些项目的源码文件复制到工作树中,要将这些文件加入到仓库中需要“生产快照”,采用以下命令:

$cd ~/dida
$git add .

所生成的快照被存放到一个临时的存储区域,称该区域为索引。Git使用每一次提交都意味着git-commit 命令可将索引提交至仓库中,这个过程称为提交,版本在进行一次更新。git-commit 最简单的用法如下:

$git commit -m “你的版本更新信息”

上述过程即为建立 Git 仓库的一般过程,git-init → git-add → git-commit。

关于建立仓库的一些细节

为来概念的完整性,上一节省略两个细节。第一个细节是你需要提交你的个人信息,提交数据到仓库事git才知道是谁提交的:

$git config --global user.name “andy”
$git config --global user.email andy@gmail.com

第二个细节是在生成文档内容快照时,工作树中有一些文档是你不希望接受Git 管理的,譬如程序编译时生成的中间文件,对于这样的文件如何避免为之生成快照?为解决此类问题, 提供了文档忽略机制,Git可以将工作树中你不希望接受 Git 管理的文档信息写到同一目录下的 .gitignore 文件中。

$cd ~/dida
$echo “zh” < .gitignore
$git add .

仓库与工作树

仓库就是那个 .git 目录,Git其中存放的是我们所提交的文档索引内容,可基于文档索引内容对其所管理的文档进行内容追踪,Git从而实现文档的版本控制。工作树是包含 .git 的目录,在前文示例中即~/dida目录。为了更加明确仓库与工作树的概念,下面做一个实验:

$ cp -R ~/dida/.git /tmp/dida.git
$ cd /tmp
$ git clone dida.git dida-copy

进入 dida-copy 目录观察一下,就会发现该目录所包含的内容是等同于 ~/dida 目录的。上述实验意味着,只要我们拥有仓库 dida.git,那么就可以很容易地生即成工作树,而这个工作树又包含着一个仓库,dida-copy/.git 。

在项目中工作

在工作树中,我们日常所进行的工作无非是对 Git 仓库所管理的文档进行修改,或者添加/删除一些文件。你认为一个工作阶段完成之时,要记得通知 Git,命令它记下你所进行更新,这一步骤是通过生成文档快照并将其加入到索引中来实现的。如:

$cd ~/dida
$git add README Facade.as

用git-add 命令将它们的更新添加到索引中。这一天的工作告以段落,我觉得有必要将今天所做的提交到仓库中,于是执行 git-commit 操作,将索引内容添加到仓库中。

$cd ~/dida
$git add .
$git commit -a

...输入日志信息... git-add 命令通常能够判断出当前目录(包括其子目录)下用户所添加的新文档并将其信息追加到索引中。

git-commit 命令的 -a 选项可将所有被修改的文档或者已删除的文档的当前状态提交倒仓库中。记住,如果只是修改或者删除了已被Git 管理的文档,是没必要使用 git-add 命令的。

查看历史版本

使用 git-log 命令可以查看当前项目的日志:

$git log

如果你想看一下每一次版本的大致变动情况,可使用以下命令

$git log --stat –summary

git-log显示结果:

commit a0f681af397e334c93fcdb5a9cbe601e6fdffb0e
Author unknown <Administrator@.(none)>
Date   Mon Dec 5 233753 2011 +0800

那一串莫名奇妙的数字为项目的版本号,有git自动生成,我们将项目版本号用作 git-show 命令的参数,即可查看该次项目版本的更新细节:

$git show a0f681af397e334c93fcdb5a9cbe601e6fdffb0e

除了使用完整的版本号查看项目版本更新细节之外,也还可以使用以下方式:

$ git show dfb02 # 一般只使用版本号的前几个字符即可
$ git show HEAD # 显示当前分支的最新版本的更新细节

每一个项目版本号通常都对应存在一个父版本号也就是项目的前一次版本状态。可使用如下命令查看当前项目版本的父版本更新细节:

$ git show HEAD^ # 查看 HEAD 的父版本更新细节
$ git show HEAD^^ # 查看 HEAD 的祖父版本更新细节
$ git show HEAD~4 # 查看 HEAD 的祖父之祖父的版本更新细节

撤销与回复

git-reset 命令就是为这样的任务而准备的,它可以将项目当前版本定位到之前提交的任何版本中。

git-reset 命令有三个选项--mixed 、 --soft 和 --hard 。我们在日常使用中仅使用前两个选项;第三个选项由于杀伤力太大,容易损坏项目仓库,需谨慎使用。

  • --mixed 是 git-reset 的默认选项,它的作用是重置索引内容,将其定位到指定的项目版本,而不改变你的工作树中的所有内容,只是提示你有哪些文件还未更新。
  • --soft 选项既不触动索引的位置,也不改变工作树中的任何内容,但是会要求它们处于一个良好的次序之内。该选项会保留你在工作树中的所有更新并使之处于待提交状态。如果欲查看 git-reset 命令对工作树的影响,可使用 git-status 命令。

使用Git帮助文档

$man git-reset
$man git reset

两种格式都可

基于Git的团队协同开发

两个人如何协同

如何解决仓库合并冲突

三人以至更多人如何协同

M2GE 的协同开发

项目分支管理

Git 最为世人称道的就是它那强大的项目分支管理功能,现在较为流行的版本控制系统,诸如CVS、SVN 等,虽然也提供了项目分支管理功能,但是可用性极低。

如何产生项目分支

前面所讲内容未有提及项目分支问题,但事实上是有一个分支存在的,就是 master 分支(主分支) 该分支是由 Git 自动产生的。在此之前,我们针对项目版本的各种操作都是在主分支上进行的,只是我们未察觉它的存在而已。

Git 可以轻松地产生新的项目分支,譬如下面操作可添加一个曰“local”的新的项目分支:

$git branch local

对于新产生的 local 分支,初始时是完全等同于主分支的。但是,local 分支在所进行的所有版本更新工作都不影响主分支,这意味着作为项目的参与者,可以在local 中开始各种各样的更新尝试。查看项目仓库中存在多少分支,可直接使用 git-branch 命令:

$git branch
  local
* master

在上述操作输出结果中,若分支名之前存在 * 符号,表示此分支为当前分支。使用 git-checkout 命令实现分支切换:

$git checkout local
分支的合并

我们产生了 local 分支,并在该分支下进行了诸多修改与数次的版本更新提交,但是该如何将这一分支的最终状态提交到 master 分支中呢?

git-merge 命令可实现两个分支的合并。

譬如我们将 local 分支与 master 分支合并,操作如下:

$ git checkout master # 将当前分支切换为master
$ git merge local # 将local分支与当前分支合并当一个分支检查无误并且与 master 分支成功合并完毕后,那么这一分支基本上就没有存在的必要性了,可以删除掉
$ git branch -d local

注意,git-branch 的 -d 选项只能删除已经参与了合并的分支,对于未有合并的分支是无法删除的。如果想不问青红皂白地删除一个分支,可以使用 git-branch 的-D 选项。

dida新的开发模式

现在来讨论一下如何基于 Git 项目分支管理功能实现更为稳健、效的高dida 库的协同开发机制。实验室服务器上已经建立了 dida 仓库。现在以 Lyr 作为主角,看一看他围绕dida 开发工作的一天中的工作过程。首先, 需要更新自己机器上的工作树,Lyr并查看实验室其他成员的版本更新信息:

$ git pull
$ git log

然后, 开始建立一个新的项目分支,Lyr将其命名为 lyr,并将当前分支切换为该分支:

$ git branch lyr
$ git checkout lyr

然后这一天中剩余的大部分时间, 都在自己所建立的项目分支上工作,Lyr譬如增加了 3 个新的接口及相关测试程序,并对原有接口做了一些修改。一天的工作完成后,他有必要将这一天的工作与 dida 仓库的 master 分支进行合并,然后删除 lyr 分支:

$ git checkout
$ git merge lyr
$ git branch -d lyr

现在, 已经将这一天的工作反映到自己机器上的 dida master 分支上了,Lyr他最后要做的是将其推送到服务器的 dida 仓库,以使项目其他成员能够分享他的工作。

这里要注意,在推送版本更新之前,需要使用 git-pull 命令将这一天中其他成员对服务器端的 dida 的更新拉过来合并到自己的 master 分支,然后才可以将自己的版本更新推送到服务器上的 dida 仓库,具体操作如下:

  1. 使用 git-pull 命令更新本地工作树;
  2. 若出现版本合并冲突,并且 Git 无法自动合并,需要手工合并,然后将合并结果提交到本地 master 分支;
  3. 使用 git-push 命令将本地 master 分支更新推送到服务器 dida 仓库中。

目前,对于我们而言,在基于 Git 的 dida 协同开发过程中,引入分支管理功能,可有效防止因个人操作不当而导致向服务器 dida 仓库提交太多的脏数据。另外,也有效保持了本地项目主分支的干净,避免了频繁 git-clone 服务器端的dida 仓库来恢复本地的项目主分支。

使用 GitHub 管理项目

Git 作为一个分布式的版本控制系统,并不存在主库这样的概念,每一份复制出的库都可以独立使用,任何两个库之间的不一致之处都可以进行合并。正因为如此,所以有了 GitHub 这个网站,GitHub 是基于ruby的并揉合多种语言进行开发的,上面的ruby项目也非常活跃。在 GitHub 中,每个人都可以有多个repo,这些repo都是与用户绑定在一起的。user 之间可以互相clone repo、fork repo、watch repo 或是 follow 其他 user,就好像 twitter 或是 plurk 等社交网站一样。

不过若使用免费的 GitHub 则所有的 repo 都要是 public 且有300M容量的限制。若希望有 private 的 repo,则需要跟付费才可。GitHub 另外还有剪贴簿的功能,可将代码贴到其中并自由的发展各种branch。

GitHub 可以托管各种git库,并提供一个web界面,但与其它像 SourceForge 或 Google Code 这样的服务不同,GitHub 的独特卖点在于从另外一个项目进行分支的简易性。

为一个项目贡献代码非常简单:首先点击项目站点的“fork”的按钮,然后将代码检出并将修改加入到刚才分出的代码库中,最后通过内建的“pull request”机制向项目负责人申请代码合并。已经有人将GitHub称为代码玩家的MySpace:

在GitHub进行分支就像在 Myspace(或Facebook [...])进行交友一样,在社会关系图的节点中不断的连线。

GitHub 项目本身自然而然的也在 GitHub 上就行托管,只不过在一个私有的,公共视图不可见的库中。开源项目可以免费托管,但私有库则并不如此。Chris Wanstrath,GitHub 的开发者之一,肯定了通过付费的私有库来在财务上支持免费库的托管这一计划。

是的,我们正是这么计划的。通过与客户的接洽,开发 FamSpam,甚至是开发 GitHub 本身,GitHub 的私有库已经被证明了物有所值。任何希望节省时间并希望和团队其它成员一样远离页面频繁转换之苦的人士都会从 GitHub 中获得他们真正想要的价值。

Chris Wanstrath还向InfoQ分享了关于GitHub的一些内幕信息:

GitHub 主要用 Rails 实现。我们目前在进行的 post-commit 集成小应用完全使用Merb编写。我们使用了 Python 的 Pygments 来做格式高亮显示,另外还用了 Ara T. Howard's Bj 加上一些 Ruby 脚本来做我们的排队系统。当然,我们用了 Ruby Grit 库来和 Git 进行交互。

GitHub 已经有了一组引人注目的特性,除了命令式的库浏览器和一个项目Wik,GitHub 甚至还包括了一个 GitHub gem,以使通过shell方式使用GitHub更为方便。更多的未来特性已经在计划中:

许多人都希望能有一个条目系统,因此一个简单的条目系统已经在开发中。此外,正如我前面所言,我们尚在进行RubyGems服务器和一些之前留出的post-commit钩子方面的工作。如果你不能或就是不想托管一个你自己的守护进程,你可以使用我们所提供的。

我们还在开发一些特性来帮助公司在使用 Github 时可以停留在sync之上。

最后,我们也在进行API发布方面的工作。我们很快就会发布一些只读性的API,随后是一些很强大的“写”集成。你可以使用API将新的事件发布到新闻feed中,发消息和做其他许多很酷的事情。

下面先來介紹如何将环境配置好,配置环境分为三个步骤,安装与设置git,安装与设置ssh-key,以及在github上注册并建立repo:

安装与设置git

请移步到前面第一节

安装与设置ssh-key

git使用ssh tunnel来提交源码,这个加密通道可以避免源码的封包被拦截而截取。因此要先产生并上传ssh key到github,方便之後与服务器之间的通迅。

Mac OS X与Linux,只要输入ssh-keygen -t rsa并根据指示操作即可:

[~/.ssh]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/tom/.ssh/id_rsa): <enter>
Enter passphrase (empty for no passphrase): <输入key的密碼,或直接按下enter使用空密码>
Enter same passphrase again: <再输入一次密码>
Your identification has been saved in /home/tom/.ssh/id_rsa.
Your public key has been saved in /home/tom/.ssh/id_rsa.pub.
The key fingerprint is:
50:43:77:c6:97:af:61:82:dc:ea:9b:6b:67:d4:1b:61 tom@volcano

其中id_rsa.pub是公钥,而id_rsa则是私钥,请妥善保存以免遺失,它们都存放于~/.ssh目录中。将公钥粘贴到你github帐号中的SSH Public Keys的位置。注意小心不要复制到空格。

Windows,执行git-bash并输入:

ssh-keygen -C “username@email.com” -t rsa

github注册

在 GitHub 你的帐号右上角可以看到一个Your Repositories,选择Create one。输入Project name后,可以看到它有教你如何创建一个新的项目。

这里以一个名为test的项目为例:

# Global setup:

# Download and install Git
git config --global user.email <your email>
git config --global user.name <your name>

# Next steps:
mkdir test # cd test
git init
# github会自动读取你的README内容并显示在项目简介中,因此先创建README
touch README
# 将README加到index中
git add README 
# 提交到版本库中
git commit -m 'first commit'
# 把github的repo加入为远程的repo
git remote add origin git@github.com:<你的ID>/test.git
# 把目前的commit状态push并同步到github上面
git push origin master

# Existing Git Repo?
cd existing_git_repo
git remote add origin git@github.com:<你的ID>/test.git
git push origin master

把你的程序push上github后就可以有自己的repo了。

若您喜欢別人的repo,只要他是public的,就可以点击上面的fork,把整个repo复制到你的帐户底下并修改提交后再请求原作者进行pull。

若你fork了一个repo(名为test)到github中之后,只要輸入:

git clone git@github.com:<ID>/test.git test

就可以将整个repo复制下来并存放在test目录中。若你的ssh key有加上密码保护,每次与github通信的过程中都需要輸入密码以存取ssh key。

git的简单使用:

# 创建一个版本库
git init
# 每次修改好了后,可以先将修改存入stage(快照/索引)中
git add <modified files>
# 修改了大量文件则使用下面这个命令批量存入
git add .
# 使用commit将快照/索引中的内容提交到版本库中
git commit -m "msg"
# 也可以将git add与git commit用一个指令完成
git commit -a -m "msg"
# 将本地的git档案与github(远程)上的同步
git push
# 将github(远程)的git档案与本地的同步(即更新本地端的repo)
git pull
# 例如,pull指令其实包含了fetch(將变更复制回來)以及merge(合并)操作
git pull git://github.com/tom/test.git

# 另外版本控制系統的branch功能也很有意思,若同时修改bug,又要加入新功能,可以fork出一个branch:一个专门修bug,一个专门加入新功能,等到稳定后再merge合并
git branch bug_fix # 建立branch,名为bug_fix
git checkout bug_fix # 切换到bug_fix
git checkout master #切换到主要的repo
git merge bug_fix #把bug_fix这个branch和现在的branch合并

# 若有remote的branch,想要查看并checkout
git branch -r # 查看远程branch
git checkout -b bug_fix_local bug_fix_remote #把本地端切换为远程的bug_fix_remote branch并命名为bug_fix_local

# 还有其它可以查看repo状态的工具
git log #可以查看每次commit的改变
git diff #可以查看最近一次改变的內容,加上参数可以看其它的改变并互相比较
git show #可以看某次的变更

# 若想知道目前工作树的状态,可以輸入
git status


source:https://github.com/wayee/flash-game-development

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值