文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏
参与翻译: luke (32)

为什么要使用Git?

Git 是一个更加现代化的版本控制系统,它提供了类似于CVS或Subversion的功能,但它不是一个重复实现的工具。Git延伸了版本控制系统的概念,它提供了无中央服务器和可离线使用的版本控制系统的功能。 这是Linus Torvalds的创意,是为了处理2005年的 “BitKeeper debacle”问题用两周时间写出了它的第一版。

现在, 开发人员都成群结队地迁移到这个激动人心的平台上。用户把高性能、灵活使用性、离线能力和协作功能作为他们切换平台的理由。让我们开始使用Git 吧。 

第 1 段(可获 1.58 积分)

分布式版本控制

如果你熟悉像Subversion一样的传统的、集中式的版本控制系统,在你迁移到Git过程中需要作出一些理念调整。 第一个没有中央服务器。第二个还是没有中央服务器。库的完整历史记录在每一个用户机器上的克隆(签出) 库中。  这是分布式版本控制系统 (DVCS)的本质。

一旦越过这些障碍,就能够完全独立自由的工作,开始版本化你的任何新项目,即使在孵化阶段。对一个新的Git repository(更常见的叫法 repo) 进行设置会让设置其它库变得更容易。

第 2 段(可获 1.68 积分)

现在你进入到第二阶段,那就是能够直接与同事共享一个仓库和一个变更集,而没有任何复杂的设置、不用签入中央服务器、直接的网络连接不用担心防火墙的阻碍。Git 拥有和BitTorrent 一样的文件共享的版本控制技术。它取消了带有中心结构的点对点模式,不再更改。 它支持通过u盘、电子邮件,或在基于网络的传统风格,如:HTTP、FTP、SCP,Samba,SSH或WebDAV进行二进方式传输变动。

第 3 段(可获 1.34 积分)

入门

安装Git

Git的安装是非常轻量级的。对于大多数平台,你可以简单把这些二进制文件放入$PATH变量中的目录中。Git主要是用C写的,这意味着每一个被支持的平台都是一个唯一的包。

Git的安装指南可以在Git的官方站点( git-scm.com/download )上找到。有很多的可用安装程序来避免手动安装的麻烦 。此外, 也可以在官方的Git下载站点下载到旧版Git二进制发行版。

第 4 段(可获 1.41 积分)

创建用户凭证

一旦选择了一个适合你平台的Git分发版,你就需要使用用户名和电子邮件地址在Git中标明自己。

作为一个纯粹主义者分离关注点事非常好的, Git 不直接支持库的认证或授权。它表示这个功能将由协议(SSH) 或主机的操作系统 (文件系统权限) 或服务存储库来提供。 因此, 在贡献代码时需要在指定机器上设置提供用户信息凭证。

第 5 段(可获 1.19 积分)

在有Git二进制的$PATH目录上,在你将使用Git新机器上得先执行如下三个命令。 把用户名和电子邮件地址替换为你自己的。

git config --global user.name “matthew.mccullough”
git config --global user.email “matthewm@ambientideas.com”
git config --global color.ui “auto”

这三个命令就是把你的配置信息存储在你home目录下一个名叫 .gitconfig的文件中 (home目录,在UNIX 和Mac系统是~,在windows上是 %USERPROFILE% )。

如果你对Git设置的细节感兴趣,可以关注GitHub,一个基于web的代码站点, 提供了几个针对 Linux,Windows和Mac的Git深入设置教程。这里有几个深入学习Git安装的指南:

http://help.github.com/win-git-installation/
http://help.github.com/mac-git-installation/
http://help.github.com/linux-git-installation/
第 6 段(可获 1.18 积分)

创建仓库

现在你已经安装好了Git且用户信息也设置好了,你就可以开始创建一个新的仓库了。 根据命令提示,切换到一个空目录下或你想使用版本控制的项目目录下。然后使用如下命令把这个目录初始化为一个Git的仓库:

git init
git add .
git commit –m ’The first commit‘

第一个命令 init 表示创建一个包含仓库历史记录和元数据的 .git 目录。与其它版本控制系统不同,Git把所有的都存储在项目根目录下的一个目录下。 以避免污染其它目录。

第 7 段(可获 1.25 积分)

接下来, add 命令后的点通配符是告诉Git开始跟踪当前目录下所有存在的文件和目录的变化。

最后, commit 功能就是把之前add的持久化到仓库的历史中。 为了不让Git提示用户使用默认文本编辑器, 使用-m 选项来提供保存文件和提交文件是的提交消息。

这是惊人的、令人兴奋的!老实说:在本地版本文件中能使用的Git基础命令就只有这三个。

第 8 段(可获 1.3 积分)

克隆已有的项目

一个Git最常见的用例是从别人的库历史开始的。这有点像Subversion或其它集中版本控制系统的 checkout 概念。 不同的是在DVCS中是接收和保存整个历史记录到用户的本地磁盘中,而不是最新版本。

从一个存在的repo下拉一个本地副本的语法如下:

git clone git://github.com/matthewmccullough/hellogitworld.git
or
git clone http://github.com/matthewmccullough/hellogitworld.git
or
git clone git@github.com:matthewmccullough/hellogitworld.git
第 9 段(可获 0.89 积分)

协议的区别通常意味着只读或可写来访问源仓库.。最后的语法, 是一个通过SSH访问的仓库,这是最常用的 Git 协议,支持仓库写操作。

clone 命令实际上是执行了几个子任务。它设置了远程 (Git仓库地址书签)名为origin并指向 git://github.com/matthewmccullough/hellogitworld.git. 接下来,向这个地址克隆这个仓库的内容。Git是通过网络以zlib压缩方式拷贝到请求者的本地磁盘上的。 最后, clone 切换到一个叫做master的分支上,相当于Subversion的trunk(主干),这也是当前的工作副本。现在这个仓库的本地副本就进入了编辑模式了,可以离线或在线的创建分支、提交。

第 10 段(可获 1.68 积分)

Git 不是使用的顺序化的修订ID,而是采用提交的变更进行SHA-1散列后的值。这就使得提交可以独立于任何中央协调服务器的。

一个完整的 SHA-1 散列值是由40位的16进制字符组成的:
64de179becc3ed324daab72f7238df1404723672

为了高效的浏览历史,下面列表中的快捷符就可以表示。 此外, 散列的任何唯一子部分都可以使用。 Git将告诉你提供的字符串是否具有唯一性。通常情况下,4-5位就足够了。

第 11 段(可获 1.3 积分)
Treeish说明
HEAD当前提交的版本
HEAD^前一个提交
HEAD^^前二个提交
HEAD~1前一个提交
HEAD~3前三个提交
:/”Reformatting all”最近的且注释是以“Reformatting all”开头的提交
RELEASE-1.0应用此标签的代码

完整的修订规范可以使用命令显示:git help rev-parse

Treeish 可用于所有的git命令,结合commit或范围commit使用。

例子:

git log HEAD~3..HEAD
git checkout HEAD^^
git merge RELEASE-1.0
第 12 段(可获 1.04 积分)

典型的本地工作流程

编辑

一旦你克隆或初始化一个新的Git项目,就可以开始修改其中的文件。没有同事加在文件上的锁,事实上, 根本没有锁。 Git是以非常乐观的方式进行操作的,相信它的合并功能是非常棒的,有能力解决和同事的任何冲突。

如果你需要移动一个文件,Git 是可以检测到你手动移动的文件并且会添加"move"显示出来。 但应该更谨慎的告诉Git:移动了文件以及在新目标中跟踪它。

第 13 段(可获 1.41 积分)
git mv originalfile.txt newsubdir/newfilename.txt

如果你希望在当前的分支中删除一个文件,你只需要告诉Git删除它即可。它将会放入到等待删除的状态区域确认并完成下一个提交。

git rm fileyouwishtodelete.txt

查看

日常工作需要强有力的支持查看仓库的当前和历史记录,查看它们的不同甚至是共同部分。 Git肯定满足这些要求。

状态

检查项目的本地目录和文件的当前状态 (修改、新增、删除或未跟踪),就调用 status命令:

git status
第 14 段(可获 1.16 积分)

对比

以补丁样式查看当前编辑完的文件与它提交的之间的不同部分,或轻易比较以前任意两个提交点上不同。 .. 操作符表示的是一个范围。在范围中省略第二个元素就是当前提交 HEAD:

git diff
git diff 32d4..
git diff --summary 32d4..

Git 允许本地文件、暂存文件、已提交文件之间进行详细的两两比较。

命令含义
git diff任何非暂存的与最新提交的对比
git diff --cached任何暂存的与最新的提交的对比
git diff HEAD任何非暂存的和暂存的与最新提交的对比
第 15 段(可获 1.33 积分)

日志

即使在无网情况下,也是可以列出所有的或从你指定时间开始到现在的更改记录:

git log
git log --since=yesterday
git log --since=2weeks

Blame

如果尝试探索某些行为什么和什么时间添加的,直截了当的使用这个命令会在源码文件的每一行上添加上带有名字和日期的Git注释:

git blame <filename>

 

第 16 段(可获 0.8 积分)

 Stashing(隐藏)

Git 提供了这样一个有用的功能:有时,修改还没有完成,还不准备提交它们,但你有需要暂时回到最新提交中 (如:最新的签出)。这个功能的名字就叫 “stash” ,它会把你所有未提交的修改放入一个栈中。

git stash

当你准备把隐藏的修改恢复到工作区时,只需要把它们从栈中弹出。

git stash pop

中止

如果你想中止当前没提交的修改恢复到最新的提交状态时,有两个命令可以帮你完成。

git reset --hard

以hard选项进行重置就是递归的舍弃你当前所有的未提交(非暂存或暂存的)的修改。

如果恢复的是一个文件,那只需使用checkout命令来恢复到最新的提交状态。

git checkout -- Person.java
第 17 段(可获 1.76 积分)

Adding (Staging)

当开发人员准备把文件作为下一次提交内容,首先得使用add命令。你可以进入任何目录,任何对文件一个一个的添加或者使用通配符。

git add <file name, folder name, or wildcard>
git add submodule1/PrimaryClass.java
git add .
git add *.java

如果add的是一个文件夹,那么git会递归的把该目录下的所有的子目录和文件添加进去。

-i选项是交互添加模式,Git会提示你输入哪些那些文件被添加哪些文件不需要添加到下次提交中。

git add -i
第 18 段(可获 0.96 积分)

 -p 选项表示激活patch 子模式,它允许你add一个文件中的一部分。

git add -p

提交

一旦内容进入到暂存区,一个commit命令就把它们放入到本地仓库中。$EDITOR 变量设置的默认文本编辑器就会打开让你填写提交注释。

git commit

也可以直接把提交注释放在命令后面,语法如下:

git commit –m”<your commit message>”

查看最后提交的统计数据和内容:

git show

如果在最后的提交注释中有错误,可以使用如下命令来修改:

git amend

(经测试 应该是:git commit --amend) 

第 19 段(可获 1.26 积分)

分支

分支看上去与其它版本控制系统一样,但不同的是Git的分支只能是本地存在的或者团队共享的(已经push上去的)简单易理解的本地分支概念,让开发人员更愿意使用分支,它可用于自己的实验性开发,因为失败了可以随意删除成功了可以合并。

git branch <new branch name> <from branch>
git branch <new branch name>
第 20 段(可获 1 积分)

选择分支

签出 (切换) 一个分支是非常简单的,如下:

git checkout <branch name>

签出本地货远程分支都是使用同一个命令,但对使用其它如Subversion版本控制系统的用户来说又有很多的不同:远程分支在“跟踪”和拷贝到本地分支之前一直是只读状态。本地分支是干活和代码提交的地方.

git branch<new branch name> <from branch>
git checkout <new branch name>

与上面两条命令等价的命令:

git checkout -b <ew branch name> <from branch>
第 21 段(可获 0.94 积分)

从Git 1.6.6开始, 有一种快捷方式来跟踪与本地分支同名的远程分支,前提是:还不存在同名的本地分支且只有一个远程分支。

<remote and local branch name>
git checkout performanceexperiment

列出所有分支

列出所有的本地与远程分支:

git branch -a

通常情况下本地分支都有一个简明的名称,如:master 、experiment。在Git的默认高亮语法中,本地分支名称都是白色的文字,远程分支有前缀 “remotes” 且是红色文字。

第 22 段(可获 1.15 积分)

合并

与其它流行的版本控制系统一样,Git允许将一个或多个分支合并到当前分支中。

git merge <branch one>
git merge <branch one> <branch two>

如果遇到Git中罕见的任何冲突时,会有一个通知消息显示且在文件里使用a >>>>>>>>> 和<<<<<<<< 把冲突部分包裹起来。 手动解决冲突后,git add该文件后,又可以像普通方式一样提交了。

Rebase

Rebase是把一个分支起点后面的所有提交放入到另一个分支中。这就可以让开发人员在自己的分支下测试修改是否正确,当然前提是有一个主干代码且包含了主干的bug修复。 

git rebase <source branch name>
git rebase <source branch name> <destination branch name>
第 23 段(可获 1.51 积分)

标签

在Git中,打标签是非常简单,与其它版本控制系统类似,但和Subversion不一样, 从提交的角度来看 标签是不可变的。 在代码中打标签的方法如下:

git tag <tag name>
git tag <tag name> <treeish>

远程工作流程

通过远程仓库一起协作是Git的一个重要功能。根据与同事的工作流程、仓库的操作系统和权限,你可以使用push或pull。Git 仓库通常是使用SSH进行共享的,但也提供了一个轻量级的守护进程实现共享。

第 24 段(可获 1.09 积分)

Git 仓库通过轻量守护进程共享的介绍:http://www.kernel.org/pub/software/scm/git/docs/git-daemon.html 

通过 SSH 和Gitosis 进行共享的详细文档: http://book.git-scm.com/4_setting_up_a_private_repository.html

Remotes

虽然大部分Git命令可以使用其它仓库是完整路径作为源或目标,但却不易处理和记忆。 用Git行话来说,这些其它仓库的书签就叫:remotes

remote又叫origin,是在克隆远程仓库时自动创建的。查看远程仓库的完整地址的方法如下:

git remote v
第 25 段(可获 1.44 积分)

添加一个新的远程名称:

git remote add <remote name> <remote address>
git remote add <remote name> git@github.com:matthewmccullough/ts.git

Push

Git中的Push就是把你本地的变化发送给同事或社区的仓库中,前提是这个仓库你有写的权限。如果你的同事也有一个推送到当前分支,那他将必须重新签出分支来使用合并引擎把你推送的变化合并到他的修改中。

Fetch

fetch是为了查看远程上的变化而不用把它们合并到你的本地分支中。它会把这些变化存储在你的工程根目录下的.git目录下,并等待下一步命令来进行源和目标的合并。

git fetch <remote name>
git merge <remote name/remote branch>
第 26 段(可获 1.41 积分)

Pull

Pull相当于 fetch与 merge的组合。

git pull
git pull <remote name>
git pull <remote name> <branch name>

Bundle

Bundle是通过U盘或邮件传输二进制差异。这些二进制差异可以使无法通过网络进行push或pull的仓库得到更新,比如:由于严格的防火墙规则无法通过网络push或pull的情况。

git bundle create catchupsusan.bundle HEAD~8..HEAD
git bundle create catchupsusan.bundle --since=10.days master
第 27 段(可获 0.83 积分)

这些差异内容可以应用到其它远程仓库,即使它们是本地磁盘上的文件。bundle的内容是可以通过ls-remote进行查看的,也可以通过fetch命令把内容放入本地仓库中。大多数Git用户都会对差异文件添加一个.bundle的后缀来作为一个约定俗成。

git ls-remote catchupsusan.bundle
git fetch catchupsusan.bundle

图形界面

在最近的两年,Git拥有了很多的图形界面。现在,很多流行语言: Ruby, Perl, Java/JVM 的集成开发环境也对Git十分友好。

第 28 段(可获 1.09 积分)

Gitk 和 Git-Gui

标准的Git分发包中提供了两个用Tcl/Tk写的图形界面。 首先, Git-Gui提供了一个面板来选择需要add和commit的文件。后者提供了一个以图形方式查看项目代码的历史和分钟信息。它们都是以当前目录作为核查仓库的。

git gui gitk

Tower, Sourcetree 等其它图形界面

这些都不是官方提供的图形界面工具。有些拥有重要的高级功能且适配了多个平台。 它们本应用得非常广泛,如:Tower, SourceTree, GitEye和GitHub Desktop。不幸的是, GitHub Desktop 目前只支持GitHub & GitHub 的企业仓库。 但鉴于GitHub是一个广泛使用的在线仓库,所以你很有可能会遇到GitHub桌面客户端。

第 29 段(可获 1.85 积分)

集成开发环境

Java的集成开发环境包括:IntelliJ, Eclipse (eGit)和NetBeans (NBGit) 都提供本地的或插件来支持Git。也有许多其他应用程序提供了直接的Git集成,如:Sublime Text 、Atom。

许多其他平台的原生界面提供了图形方式来浏览历史、可视化分支、合并、暂存、提交功能。

CVS, Subversion

在互操作性方面,令人惊奇的是Git提供了读写远程Subversion 或 CVS 仓库的能力,这也是使用Git的另一个好处。

第 30 段(可获 1.4 积分)

克隆

为了把Subversion仓库中的主干、标签、分支转换到Git仓库中,可以使用如下的语法:

git svn clone --stdlayout <svn repo url>

请耐心等待,并注意进度消息。 克隆一个大的Subversion仓库可能需要几个小时。

把Git的commit推送到Subversion

Git的commit是可以以事务的方式的推送的,一个一个的克隆到Subversion仓库中。 当想把Git commit分享给Subversion 同事时,使用如下命令:

git svn dcommit
第 31 段(可获 1.05 积分)

获取Subversion的修改

当在Subversion中不可避免的修改后,又需把这些变化放入Git仓库中, rebase到Subversion 仓库的最新状态,如下:

git svn rebase

高级命令

Git提供了针对新手和专家使用的命令。有些Git功能需要使用下列资源进行深入学习理解。这些高级功能包括内置的 (manpage-like) help 和使用show-branch ASCII艺术化展示分支合并状态。 Git 也提供了使用revert 命令还原最后一次commiti, 二进制搜索(bisect) 导致单元测试失败的一系列历史, 使用fsck检测仓库的完整性,使用gc修剪代码树上任何孤立的点,使用grep进行历史搜索。而这仅仅是开始。

本文展示了丰富而深刻的Git分布式版本控制系统,对于大胆使用新的代码协作和版本控制的新人来说仍然是平易近人。

第 32 段(可获 2.15 积分)

文章评论

coyee
@luke 感觉你没用过 git ,估计这篇文章翻译完你对 git 就会了解得比较深入
luke
实际上是用过,且正在用,只是表达能力不好,自己明白什么意思,写出来就有点变味了。继续努力改进。
coyee
那还好,我发现翻译最大的障碍还是我们的母语 —— 中文 :)