git集中式vs分布式
版本控制系统(VCS)提供了一种机制,用于对项目中的文件集应用和管理更改,并且通常用于面向团队的软件,文档和其他在线开发项目中。 VCS对开发项目和系统备份一样重要,因为它们使多个用户可以将更改提交到相同的文件或项目,而一个开发人员的更改不会意外覆盖另一个开发人员。
即使Linus Torvalds尚未开发Linux®操作系统内核,他也可能以创建Git VCS而闻名。 像Linux这样复杂的项目是VCS的最终系统测试,因此GitSwift发展成为一个稳定,强大且灵活的系统也就不足为奇了。
Linux和UNIX®系统深深扎根于VCS中,从诸如修订版控制系统(RCS)和并发版本系统(CVS)的恐龙到诸如Subversion,Mercurial,Bazaar,Arch和Darcs之类的更现代的系统。 具有讽刺意味的是(尤其是在Linux领域),Git是作为商用VCS(称为BitKeeper)的替代品开发的,它既具有独特的功能,又具有令人印象深刻的功能,并且具有免费版本。 BitKeeper仍然令人印象深刻,但是许可变更最终导致Torvalds寻找替代方案。 在最好的自由软件传统中,他最终决定自己编写。 像Linux内核一样,Git现在是增强功能,错误修复以及无数开源开发人员的其他贡献的产物。
Git的强大功能和与免费软件相关的成本节省都具有吸引力,Git很快就被许多开源软件项目,学术机构和组织所采用。 一旦“进入”公司或学术环境,Git作为VCS和协作平台的优势便导致其在传统“源代码”领域之外的许多项目中得到采用。 正如本文讨论的那样,Git在具有内容和开发要求的复杂的分布式Web开发项目中特别有用,因此需要不同人员之间的最新交互。
Git:不仅仅是VCS
Git旨在促进成千上万的开发人员之间的分布式开发,这些开发人员在具有不同程度的Internet连接的许多不同位置工作,而不会引入明显的性能或访问瓶颈。 支持Git中这些基本要求的最重要方面是:
- 使用中央存储库,但为项目中的每个开发人员提供该项目源代码的完整副本。 这保证了所有开发人员都可以完成工作,而无论其当前的连接性如何。
- 为在软件项目中创建不同的工作集(称为分支)并在其中共享更改(称为合并)提供快速可靠的支持。 分支使支持软件包的不同版本变得容易,无论这些版本是永久版本还是为实验而创建。 合并通常是源代码控制系统的关键方面,在面向分支的VCS中尤其常见。
- 使开发人员子集之间共享正在进行的分支和代码更改变得容易,而无需先将这些更改签入中央存储库。
这些设计决策及其实现是Git成功和可用性的关键方面。 当然,Git还满足标准的VCS要求,例如不变性和责任制。 不变性意味着一旦将更改提交给存储库,它们便是项目历史记录的永久部分。 即使随后可以撤消更改(称为reverting ),更改和撤消这些更改的替换代码都是项目历史的永久部分。 问责制意味着可以轻松确定谁进行了特定更改以及何时进行了更改。 为什么进行更改可能仍然是一个谜(尽管在进行更改时需要一些注释),但至少您知道该问谁。
Git使用内部索引来跟踪存储库中文件和目录的状态。 它还存储反映这些文件和目录更改的对象,以简化后续更新。 Git的索引和这些对象不同于本地存储库中存在的实际文件和目录,该模型可以轻松识别在本地已更改但尚未提交到本地存储库或远程中央存储库的文件和目录(如果有的话)。 一些Git命令对索引进行操作,而另一些命令对实际的文件和目录内容进行操作,如果您使用了错误的命令,可能会造成混淆,并且想知道为什么文件没有更新。
获得Git
大多数Linux发行版在其软件包存储库中提供Git软件包。 在使用.deb软件包格式的Ubuntu,Debian和类似系统上,您需要安装git-core软件包。 在基于RPM的系统(例如Fedora,Red Hat,Centos,SUSE和Mandriva)上,主要的Git软件包简称为git。 基本的Git软件包要求在系统上还安装Perl,用于加密和错误处理的Perl库以及补丁实用程序。
如果您的Linux系统需要最新最好的Git版本,则Git网站提供了指向预打包的.deb和RPM软件包的链接,以及最新的Git源代码(如果您要构建自己的版本)。 Git站点还提供指向Mac®OS X,本地Windows®,Windows系统上的Cygwin和Sun / OracleSolaris®系统的Git的预编译版本的链接。 目前,IBM®AIX®和Hewlett-Packard®HP-UX系统管理员必须从其平台的源代码构建Git。 请参阅相关主题以获取有关或Git的建设为平台的信息。
主要的Git软件包包含git可执行文件和一些辅助的Git应用程序。 如您所料,也提供了大量其他与Git相关的软件包。 一些与Git相关的最受欢迎的软件包包括:
- git-cola。 一个用于在Git存储库中处理文件和目录的GUI
- git-doc。 在本地安装Git用户手册,教程和文档
- git-gui。 用于浏览和使用Git存储库的GUI; 使用gitk包
- git-web。 Git存储库的基于Web的图形化界面
- gitk。 一个用于浏览和使用Git存储库的简单GUI
- qgit。 一个基于Qt的图形化应用程序,用于查看和浏览Git存储库
git-gui,git-web,gitk和qgit软件包提供了相似的功能,尽管git-web是基于Web的,而所有其他软件包都在本地运行。 尽管git-web软件包可能是分布式环境中的最佳选择,但是当您开始使用Git时,这些软件包中的任何一个都是有用的。
如果您对尝试使用Git感兴趣,但已经承诺使用另一个VCS,则以下软件包可能会有用:
- git-cvs。 该软件包提供了Git与CVS信息库之间的互操作性,使您能够导入CVS信息库并将更改历史记录导入Git,在Git中工作,将更改合并回CVS信息库,以及从CVS信息库导入更新。
- git-svn。 该软件包提供了Git和Subversion信息库之间的互操作性,使您可以将Subversion信息库和更改历史记录导入Git,在Git中工作,将更改合并回Subversion信息库,以及从Subversion信息库导入更新。
通用Git命令
Git在传统上称为命令套件,这意味着您使用的主要命令是git
并且命令行上的第一个参数指示您要运行的特定Git命令。
您可以随时运行不带参数的git
命令,随时查看常见的Git命令列表。 以下是此列表的子集:
-
add
。 将新文件添加到Git的索引中。 您仍然必须提交此文件,以将其内容实际添加到Git存储库。 -
branch
。 使您可以列出已签出的分支,标识当前正在使用的分支,创建新分支或销毁已创建或签出的分支的本地副本。 该命令不会切换到其他分支:您可以使用Git的checkout
命令来执行此操作。 -
checkout
。 签出指定的分支或文件/目录。 如果您要签出分支,则该分支将成为您的工作分支。 如果您指定某个文件或目录,那么该文件或目录将被更新以匹配当前签入到您所在分支的存储库中的版本。 您还可以使用此命令来创建一个新分支,该分支基于并可以跟踪对指定现有分支的更改。 -
commit
。 在Git的索引中记录对文件和目录的更改。 您可以指定要提交更改的文件和目录,可以使用-a
选项将所有待处理的更改添加到Git跟踪的文件中,也可以使用--interactive
选项选择要提交的文件或目录更改一起。 (如果您要处理涉及大量文件的多个不同任务,但又想一起提交某些更改,则后者特别有用。对本地存储库进行提交;如果使用远程中央存储库,则仍必须使用Git的push
命令将本地更改推送到远程存储库。) -
diff
显示本地文件与其他提交之间的差异或两次不同提交中的文件之间的差异。 仅通过指定文件名即可最常使用此命令,该文件名显示指定文件与提交到当前分支上的存储库的文件版本之间的差异。 -
fetch
。 从另一个存储库检索索引更新,标识已创建的新标签,并提供有关已提交到该存储库但尚未本地显示的文件或目录更改的信息。 然后,您可以使用git log
命令检查可用的更改。 要在提取后实际检索关联的文件更改,可以使用git pull
或git rebase
命令。 -
grep
。 在当前分支的文件中查找并显示模式的匹配项。 此命令支持大多数您喜欢的GNUgrep
选项。 -
log
。 显示当前分支或当前分支中指定文件的提交日志信息。 -
merge
。 合并从一个分支到另一个分支的更改。 此命令提供选项来确定是否自动提交合并的更改,从而使您能够在实际接受这些更改之前探索合并的影响。 -
mv
重命名Git当前正在跟踪的文件,目录或符号链接。 -
pull
。 从另一个存储库中检索索引更新,并将它们合并到当前分支中的文件和目录中。 -
push
。 使用本地索引和对象更改信息更新远程存储库。 -
rebase
。 更新当前分支以匹配远程分支,并修改尚未推送到远程分支的所有本地提交,以便可以将其应用于该远程分支的当前状态。 这是一个功能强大但潜在危险的命令,因为它会按需重写提交,以便可以将它们合并。 根据远程存储库更改的频率和程度,仅使用git pull
命令通常是一种有吸引力的选择。 -
rm
。 删除Git当前正在跟踪的文件,目录或符号链接。 -
stash
。 暂时将您当前的更改推送到堆栈上,并将当前签出状态返回到原始状态。git stash save
将您当前的更改保存在本地堆栈中,而git stash apply
检索并重新应用它们。 当您要获取远程更改或重新设置基准而不永久提交正在进行的更改时,此功能很有用。 -
status
。 显示当前分支的状态,标识尚未提交的更改,未被跟踪的文件,等等。
所有的Git命令都接受--help
选项,当您试图获取有关任何这些命令的更详细信息,每个命令都接受的命令行选项的列表等时,这是您最好的朋友。 您也可以执行命令git help command
以获得有关任何Git命令的帮助。
有关Git命令的完整列表,请执行man git
命令以查看Git的在线参考信息。
设置一个新的Git项目
要对不受任何版本控制的现有项目开始使用Git,请执行以下步骤:
- 转到包含项目源代码的目录:
$ cd www.move2linux.com $ ls greenbar_wide.gif images index.html legacy.html services.html
- 使用
git init
命令在当前目录中创建一个空的存储库:$ git init Initialized empty Git repository in .git/
- (可选)使用
git status
命令检查新项目的状态。此命令将当前目录中的所有文件和目录列出为未跟踪,这意味着Git知道它们存在但未被指示跟踪文件:
$ git status # On branch master # # Initial commit # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # greenbar_wide.gif # images/ # index.html # legacy.html # services.html nothing added to commit but untracked files present...
- 将项目中的文件和目录添加到新的Git存储库中。
您可以显式列出它们,也可以使用句点(
.
)作为“当前目录内容”的传统快捷方式:$ git add .
- 重新执行
git status
命令,以验证当前目录及其所有子目录中的所有文件已添加到新项目中:$ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: greenbar_wide.gif # new file: images/digits/b/0.gif # new file: images/digits/b/1.gif # new file: images/digits/b/4.gif # new file: images/digits/b/5.gif # new file: images/digits/b/6.gif # new file: images/digits/b/7.gif # new file: images/digits/b/8.gif # new file: images/digits/b/9.gif # new file: index.html # new file: legacy.html # new file: services.html #
- 执行
git commit
命令以检入您的初始文件。除非您在命令行上使用
-m " commit message "
选项指定您的提交消息,否则此命令将启动默认编辑器,在该编辑器中,您必须输入将与该提交关联的注释。 保存评论并退出编辑器后,Git签入与更改关联的文件,并显示有关提交和关联文件的信息。$ git commit Created initial commit dfbd6cc: Initial checkin 12 files changed, 285 insertions(+), 0 deletions(-) ...
至此,您已经准备好使用上面讨论的命令来开始使用Git处理项目文件。
对现有的Git项目进行更改
如果您要开始对某人已经创建的Git项目进行自己的更改,那么上手会更加容易。 您只需使用git clone
命令来创建自己的Git项目工作副本:
$ git clone /home/jake/src/maps
本示例在您当前的工作目录中创建Git maps项目的副本。 然后,您可以将目录更改为maps项目的副本,并使用前面讨论的命令开始在Git中使用该项目中的文件。
克隆一个Git项目
克隆位于另一台机器上的Git项目也同样简单。 Git默认情况下支持安全外壳(SSH)和HTTP协议,并且如果远程系统上正在运行Git守护程序并导出您感兴趣的项目,Git也可以使用其自己的超高效git协议。Git默认情况下使用SSH ,因此通过SSH克隆存储库的语法正是您所期望的:
$ git clone remote-machine:/home/jake/src/maps
$ git clone ssh://remote-machine/home/jake/src/maps
注意:通过SSH克隆Git项目要求您具有对远程系统的身份验证访问权限,这是使用git协议的一个很好的论据,即使它要求您运行Git守护程序。
使用Git进行分布式Web开发
诸如您上面创建的存储库之类的存储库包含Git项目中所有文件的工作副本,以及Git用于跟踪更改,分支,标签等所需的所有文件。 默认情况下,推送到包含项目中文件工作副本的Git存储库只会更新该项目的索引,而不更新项目中的实际文件。 这是因为如果您还要处理相同的文件,则尝试自行更新文件可能会导致合并冲突。
要创建您可以推送到的Git项目,您需要创建一个称为裸仓库的仓库,即不包含文件的工作副本但包含Git索引,反映该索引更新的对象,和Git所需的其他文件。 因为光秃秃的存储库不包含文件的工作副本,所以没有人可以在那里实际工作,它只是作为所有处理包含该项目的开发人员的集合点。
执行以下步骤,在包含您网站内容以及您和其他开发人员可以推送到的网站内容的Web服务器上创建Git存储库。 此过程还将现有的Web内容目录替换为包含新Git存储库的检出版本的目录,并且只要将文件推送到共享Git存储库,该目录就会自动更新。 有许多方法可以做到这一点:此示例旨在易于理解,因此仅涉及您网站上HTML内容。 您可以遵循相同的原则在网站的任何其他部分上工作。
- 在Web服务器上使用SSH,然后切换到包含Web内容的目录。
如果Git尚未跟踪您的Web内容,请使用上一节中描述的过程在此处设置Git存储库。 例如:
$ ssh somehost $ cd /var/www/html $ git init $ git add . $ git commit -m "Initial commit"
- 将目录上移一个级别,并通过克隆您刚刚为Web内容创建的项目来创建裸Git存储库:
$ cd .. $ git clone --bare html html.git
优良作法是使用.git扩展名创建裸存储库,以便您可以使用诸如gitweb之类的工具(需要此扩展名)进行查看。
- 重命名现有的Web目录,并通过克隆裸存储库使用相同的名称创建一个新的Git项目:
$ mv html html.OLD && git clone html.git html
新项目目录包含Git项目中与您的Web服务器内容相对应的所有文件的签出版本。
- 在裸存储库的hooks子目录中编辑(或创建)更新后脚本,该更改将更改推送到包含您的Web内容已签出文件的新项目目录中。
在您的裸仓库跟踪的任何文件更新后,该脚本将执行一次。 确保此脚本是可执行的:
$ pushd html.git/hooks $ emacs post-update $ chmod 755 post-update
更新后脚本应类似于清单1 。
清单1.更新后脚本
#!/bin/bash # WEB_DIR="/var/www/html" export GIT_DIR="$WEB_DIR/.git" pushd $WEB_DIR > /dev/null git pull popd > /dev/null
请注意,此脚本必须使用/ bin / bash作为其解释器,才能使用该Shell的
pushd
和popd
内置命令。 如果更新后文件已经存在,则可以在验证解释器后将脚本的其余部分简单地附加到文件中。 您还必须确保在现有更新后脚本中的所有现有命令之前都没有exec
命令,这将阻止执行文件中的后续行。
此时,您或任何其他开发人员都可以在Web服务器上克隆裸存储库,然后开始在您的网站上工作。 然后,您和任何其他开发人员都可以通过执行以下任何任务来共同处理构成您的网站的文件:
- 在您的网站签出中处理文件,然后将它们直接推送到共享的中央存储库。
- 在您的网站结帐中处理文件,并让同事将已提交的更改从您的结帐中拉入他或她的文件。 这使您可以在将文件推送到共享的中央存储库并因此推送到您的网站之前,协同工作文件。
尽管Git的速度比大多数VCS快得多,但是如果您使用的是大型且复杂的网站,则直接在网站目录中工作可能是不切实际的。 访问者可能会意外收到某些文件的更新,而其他文件尚未更新。 如果加载使用CSS更新的页面时未收到CSS更新,则这可能会特别成问题。 您通常可以使用Web服务器中的符号链接之类的解决方案来实际指向您的目录,并在您希望更新的内容上线时切换它们,或者通过修改Web服务器配置文件以使其优雅地指向另一个目录,来防止此问题。当您希望新内容上线时,请重新启动Web服务器。
结论
Git是功能强大且灵活的VCS,由于它是针对其设计的分布式受众而提供许多协作功能的。 Git正在以新的和不同的方式来实现协作开发,包括网站,基于Web的应用程序的共享开发等,并且花时间理解它的内部结构和学习Git命令的子集是非常值得的用。
翻译自: https://www.ibm.com/developerworks/web/library/wa-git/index.html
git集中式vs分布式