<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>浮山狼de博客 &#187; 版本控制</title>
	<atom:link href="https://www.fushanlang.com/category/programming-skill/version-control/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.fushanlang.com</link>
	<description>next station - 下一站，活在当下，且行且思</description>
	<lastBuildDate>Sat, 29 Nov 2014 15:14:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.2.5</generator>
	<item>
		<title>Git-基础篇</title>
		<link>https://www.fushanlang.com/git-basics-529/</link>
		<comments>https://www.fushanlang.com/git-basics-529/#comments</comments>
		<pubDate>Tue, 14 Sep 2010 01:57:15 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[版本控制]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[版本]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=529</guid>
		<description><![CDATA[<p>Git是什么 Git在Wikipedia上的定义：它是一个免费的、分布式的版本控制工具，或是一个强调了速度快的源代码管理工具。Git最初被Linus Torvalds开发出来用于管理Linux内核的开发。每一个Git的工作目录都是一个完全独立的代码库，并拥有完整的历史记录和版本追踪能力，不依赖于网络和中心服务器。</p> <p>Git的出现减轻了许多开发者和开源项目对于管理分支代码的压力，由于对分支的良好控制，更鼓励开发者对自己感兴趣的项目做出贡献。其实许多开源项目包括Linux kernel, Samba, X.org Server, Ruby on Rails，都已经过渡到使用Git作为自己的版本控制工具。对于我们这些喜欢写代码的开发者嘛，有两点最大的好处，我们可以在任何地点（在上班的地铁上）提交自己的代码和查看代码版本；我们可以开许许多多个分支来实践我们的想法，而合并这些分支的开销几乎可以忽略不计。</p> <p>Git 1+1 现在进入本篇文章真正的主题，介绍一下Git的基本命令和操作，会从Git的版本库的初始化，基本操作和独有的常用命令三部分着手，让大家能够开始使用Git。</p> <p>Git通常有两种方式来进行初始化:</p> git clone: 这是较为简单的一种初始化方式，当你已经有一个远程的Git版本库，只需要在本地克隆一份，例如&#8217;git clone git://github.com/someone/some_project.git some_project&#8217;命令就是将&#8217;git://github.com/someone/some_project.git&#8217;这个URL地址的远程版 本库完全克隆到本地some_project目录下面 git init和git remote：这种方式稍微复杂一些，当你本地创建了一个工作目录，你可以进入这个目录，使用&#8217;git init&#8217;命令进行初始化，Git以后就会对该目录下的文件进行版本控制，这时候如果你需要将它放到远程服务器上，可以在远程服务器上创建一个目录，并把 可访问的URL记录下来，此时你就可以利用&#8217;git remote add&#8217;命令来增加一个远程服务器端，例如&#8217;git remote add origin git://github.com/someone/another_project.git&#8217;这条命令就会增加URL地址为&#8217;git: //github.com/someone/another_project.git&#8217;，名称为origin的远程服务器，以后提交代码的时候只需要使用 origin别名即可 <p>现在我们有了本地和远程的版本库，让我们来试着用用Git的基本命令吧：</p> git pull：从其他的版本库（既可以是远程的也可以是本地的）将代码更新到本地，例如：&#8217;git pull origin master&#8217;就是将origin这个版本库的代码更新到本地的master主枝，该功能类似于SVN的update git add：是将当前更改或者新增的文件加入到Git的索引中，加入到Git的索引中就表示记入了版本历史中，这也是提交之前所需要执行的一步，例如&#8217;git add app/model/user.rb&#8217;就会增加app/model/user.rb文件到Git的索引中 git rm：从当前的工作空间中和索引中删除文件，例如&#8217;git rm app/model/user.rb&#8217; git commit：提交当前工作空间的修改内容，类似于SVN的commit命令，例如&#8217;git commit -m &#8220;story <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/git-basics-529/">Git-基础篇</a></span>]]></description>
				<content:encoded><![CDATA[<p>Git是什么<br />
Git在Wikipedia上的定义：它是一个免费的、分布式的版本控制工具，或是一个强调了速度快的源代码管理工具。Git最初被Linus  Torvalds开发出来用于管理Linux内核的开发。每一个Git的工作目录都是一个完全独立的代码库，并拥有完整的历史记录和版本追踪能力，不依赖于网络和中心服务器。</p>
<p>Git的出现减轻了许多开发者和开源项目对于管理分支代码的压力，由于对分支的良好控制，更鼓励开发者对自己感兴趣的项目做出贡献。其实许多开源项目包括Linux  kernel, Samba, X.org Server, Ruby on  Rails，都已经过渡到使用Git作为自己的版本控制工具。对于我们这些喜欢写代码的开发者嘛，有两点最大的好处，我们可以在任何地点（在上班的地铁上）提交自己的代码和查看代码版本；我们可以开许许多多个分支来实践我们的想法，而合并这些分支的开销几乎可以忽略不计。<span id="more-529"></span></p>
<p>Git  1+1<br />
现在进入本篇文章真正的主题，介绍一下Git的基本命令和操作，会从Git的版本库的初始化，基本操作和独有的常用命令三部分着手，让大家能够开始使用Git。</p>
<p>Git通常有两种方式来进行初始化:</p>
<ul>
<li>git clone:  这是较为简单的一种初始化方式，当你已经有一个远程的Git版本库，只需要在本地克隆一份，例如&#8217;git clone  git://github.com/someone/some_project.git  some_project&#8217;命令就是将&#8217;git://github.com/someone/some_project.git&#8217;这个URL地址的远程版  本库完全克隆到本地some_project目录下面</li>
<li>git init和git  remote：这种方式稍微复杂一些，当你本地创建了一个工作目录，你可以进入这个目录，使用&#8217;git  init&#8217;命令进行初始化，Git以后就会对该目录下的文件进行版本控制，这时候如果你需要将它放到远程服务器上，可以在远程服务器上创建一个目录，并把  可访问的URL记录下来，此时你就可以利用&#8217;git remote add&#8217;命令来增加一个远程服务器端，例如&#8217;git remote add origin  git://github.com/someone/another_project.git&#8217;这条命令就会增加URL地址为&#8217;git:  //github.com/someone/another_project.git&#8217;，名称为origin的远程服务器，以后提交代码的时候只需要使用  origin别名即可</li>
</ul>
<p>现在我们有了本地和远程的版本库，让我们来试着用用Git的基本命令吧：</p>
<ul>
<li>git  pull：从其他的版本库（既可以是远程的也可以是本地的）将代码更新到本地，例如：&#8217;git pull origin  master&#8217;就是将origin这个版本库的代码更新到本地的master主枝，该功能类似于SVN的update</li>
<li>git  add：是将当前更改或者新增的文件加入到Git的索引中，加入到Git的索引中就表示记入了版本历史中，这也是提交之前所需要执行的一步，例如&#8217;git add  app/model/user.rb&#8217;就会增加app/model/user.rb文件到Git的索引中</li>
<li>git rm：从当前的工作空间中和索引中删除文件，例如&#8217;git  rm app/model/user.rb&#8217;</li>
<li>git  commit：提交当前工作空间的修改内容，类似于SVN的commit命令，例如&#8217;git commit -m &#8220;story #3, add user  model&#8221;&#8216;，提交的时候必须用-m来输入一条提交信息</li>
<li>git  push：将本地commit的代码更新到远程版本库中，例如&#8217;git push origin&#8217;就会将本地的代码更新到名为orgin的远程版本库中</li>
<li>git log：查看历史日志</li>
<li>git  revert：还原一个版本的修改，必须提供一个具体的Git版本号，例如&#8217;git revert  bbaf6fb5060b4875b18ff9ff637ce118256d6f20&#8217;，Git的版本号都是生成的一个哈希值</li>
</ul>
<p>上面的命令几乎都是每个版本控制工具所公有的，下面就开始尝试一下Git独有的一些命令：</p>
<ul>
<li>git branch：对分支的增、删、查等操作，例如&#8217;git  branch new_branch&#8217;会从当前的工作版本创建一个叫做new_branch的新分支，&#8217;git branch -D  new_branch&#8217;就会强制删除叫做new_branch的分支，&#8217;git branch&#8217;就会列出本地所有的分支</li>
<li>git  checkout：Git的checkout有两个作用，其一是在不同的branch之间进行切换，例如&#8217;git checkout  new_branch&#8217;就会切换到new_branch的分支上去；另一个功能是还原代码的作用，例如&#8217;git checkout  app/model/user.rb&#8217;就会将user.rb文件从上一个已提交的版本中更新回来，未提交的内容全部会回滚</li>
<li>git  rebase：用下面两幅图解释会比较清楚一些，rebase命令执行后，实际上是将分支点从C移到了G，这样分支也就具有了从C到G的功能</li>
</ul>
<p><img src="http://www.fushanlang.com/blog/wp-content/uploads/auto_save_image/2010/09/095716U12.jpg" alt="" width="510" height="174" /></p>
<div>
<ul>
<li>git  reset：将当前的工作目录完全回滚到指定的版本号，假设如下图，我们有A-G五次提交的版本，其中C的版本号是  bbaf6fb5060b4875b18ff9ff637ce118256d6f20，我们执行了&#8217;git reset  bbaf6fb5060b4875b18ff9ff637ce118256d6f20&#8217;那么结果就只剩下了A-C三个提交的版本</li>
</ul>
</div>
<div id="fhzj"><img src="http://www.fushanlang.com/blog/wp-content/uploads/auto_save_image/2010/09/095717fp9.jpg" alt="" width="362" height="115" /></div>
<ul>
<li>git  stash：将当前未提交的工作存入Git工作栈中，时机成熟的时候再应用回来，这里暂时提一下这个命令的用法，后面在技巧篇会重点讲解</li>
<li>git  config：利用这个命令可以新增、更改Git的各种设置，例如&#8217;git config branch.master.remote  origin&#8217;就将master的远程版本库设置为别名叫做origin版本库，后面在技巧篇会利用这个命令个性化设置你的Git，为你打造独一无二的 Git</li>
<li>git  tag：可以将某个具体的版本打上一个标签，这样你就不需要记忆复杂的版本号哈希值了，例如你可以使用&#8217;git tag revert_version  bbaf6fb5060b4875b18ff9ff637ce118256d6f20&#8217;来标记这个被你还原的版本，那么以后你想查看该版本时，就可以使用  revert_version标签名，而不是哈希值了</li>
</ul>
<p>Git之所以能够提供方便的本地分支等特性，是与它的文件存储机制有关的。Git存储版本控制信息时使用它自己定义的一套文件系统存储机制，在代码根目录下有一个.git文件夹，会有如下这样的目录结构：</p>
<div id="xa1."><img src="http://www.fushanlang.com/blog/wp-content/uploads/auto_save_image/2010/09/095717x8W.jpg" alt="点击查看原始尺寸" /><br />
有几个比较重要的文件和目录需要解释一下：HEAD文件存放根节点的信息，其实目录结构就表示一个树型结构，Git采用这种树形结构来存储版本信息，那么HEAD就表示根；refs目录存储了你在当前版本控制目录下的各种不同引用（引用指的是你本地和远程所用到的各个树分支的信息），它有heads、remotes、stash、tags四个子目录，分别存储对不同的根、远程版本库、Git栈和标签的四种引用，你可以通过命令&#8217;git  show-ref&#8217;更清晰地查看引用信息；logs目录根据不同的引用存储了日志信息。因此，Git只需要代码根目录下的这一个.git目录就可以记录完整的版本控制信息，而不是像SVN那样根目录和子目录下都有.svn目录。那么下面就来看一下Git与SVN的区别吧</div>
<p>Git与SVN的不同<br />
SVN（Subversion）是当前使用最多的版本控制工具。与它相比较，Git最大的优势在于两点：易于本地增加分支和分布式的特性。</p>
<p>下面两幅图可以形象的展示Git与SVN的不同之处<br />
<img id="cyqr" src="http://www.fushanlang.com/blog/wp-content/uploads/auto_save_image/2010/09/095717uRU.jpg" alt="" width="494" height="241" /></p>
<div><img id="j.e:" src="http://www.fushanlang.com/blog/wp-content/uploads/auto_save_image/2010/09/095718ODD.jpg" alt="" width="495" height="242" /></div>
<p>对于易于本地增加分支，图中Git本地和服务器端结构都很灵活，所有版本都存储在一个目录中，你只需要进行分支的切换即可达到在某个分支工作的效果。而SVN则完全不同，如果你需要在本地试验一些自己的代码，只能本地维护多个不同的拷贝，每个拷贝对应一个SVN服务器地址。举一个实际的例子，以前我所在的小组使用SVN作为版本控制工具，当我正在试图增强一个模块，工作做到一半，由于会改变原模块的行为导致代码服务器上许多测试的失败，所以并没有提交代码。这时候上级对我说，现在有一个很紧急的Bug需要处理，  必须在两个小时内完成。我只好将本地的所有修改diff，并输出成为一个patch文件，然后回滚有关当前任务的所有代码，再开始修改Bug的任务，等到修改好后，在将patch应用回来。前前后后要完成多个繁琐的步骤，这还不计中间代码发生冲突所要进行的工作量。可是如果使用Git，  我们只需要开一个分支或者转回到主分支上，就可以随时开始Bug修改的任务，完成之后，只要切换到原来的分支就可以优雅的继续以前的任务。只要你愿意，每一个新的任务都可以开一个分支，完成后，再将它合并到主分支上，轻松而优雅。</p>
<p>分布式对于Git而言，你可以本地提交代码，所以在上面的图中，Git有利于将一个大任务分解，进行本地的多次提交，而SVN只能在本地进行大量的一次性更改，导致将来合并到主干上造成巨大的风险。Git的代码日志是在本地的，可以随时查看。SVN的日志在服务器上的，每次查看日志需要先从服务器上下载下来。我工作的小组，代码服务器在美国，每次查看小组几年前所做的工作时，日志下载就需要十分钟，这不能不说是一个痛苦。后来我们迁移到Git上，利用Git日志在本地的特性，我用Ruby编写了一个Rake脚本，可以查看某个具体任务的所有代码历史，每次只需要几秒钟，大大方便我的工作。当然分布式并不是说用了Git就不需要一个代码中心服务器，如果你工作在一个团队里，还是需要一个服务器来保存所有的代码的。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/git-basics-529/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>git常用命令</title>
		<link>https://www.fushanlang.com/git-commonly-used-commands-525/</link>
		<comments>https://www.fushanlang.com/git-commonly-used-commands-525/#comments</comments>
		<pubDate>Tue, 14 Sep 2010 01:38:35 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[版本控制]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[版本]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=525</guid>
		<description><![CDATA[<p>[基本仓库]： 拥有 GIT 仓库的人需要的命令——也就是所有人，因为 git 的每个工作拷贝都是一个仓库。</p> <p>之后，[个人开发者 (独立工作)]： 任何需要进行 commit 的人都需要的命令，即使是一个人工作的情况。</p> <p>如果你和其他人一起工作，你还需要列在[个人开发者 (参与者)]小节的命令。</p> <p>扮演[集成者]角色的人还需要学习这一节中的命令。</p> <p>[仓库管理]命令是给哪些负责维护 GIT 仓库的系统管理员的。</p> 基本仓库 <p>所有人都可以用这些命令来维护 git 仓库。</p> git-init(1) 或 git-clone(1) : 创建一个新仓库。 git-fsck(1) : 检查仓库的错误。 git-gc(1) 进行日常维护工作，如 repack 或 prune。 实例： 检查健康状况并去除无用的内容 (译注：cruft 不知如此翻译是否妥当，git-gc 基本是这个含义)。 $ git fsck (1) $ git count-objects (2) $ git gc (3) 不加–full参数的情况下，这个命令一般会以非常低廉的代价确保仓库在一个不错的健康状态之中。 统计有多少松散的对象，没有 repack 的对象消耗了多少硬盘空间。 <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/git-commonly-used-commands-525/">git常用命令</a></span>]]></description>
				<content:encoded><![CDATA[<p>[基本仓库]： 拥有 GIT 仓库的人需要的命令——也就是所有人，因为 git 的每个工作拷贝都是一个仓库。</p>
<p>之后，[个人开发者 (独立工作)]： 任何需要进行 commit 的人都需要的命令，即使是一个人工作的情况。</p>
<p>如果你和其他人一起工作，你还需要列在[个人开发者 (参与者)]小节的命令。</p>
<p>扮演[集成者]角色的人还需要学习这一节中的命令。</p>
<p>[仓库管理]命令是给哪些负责维护 GIT 仓库的系统管理员的。</p>
<h2>基本仓库</h2>
<p>所有人都可以用这些命令来维护 git 仓库。</p>
<ul>
<li>git-init(1) 或 git-clone(1) : 创建一个新仓库。</li>
<li>git-fsck(1) : 检查仓库的错误。</li>
<li>git-gc(1) 进行日常维护工作，如 repack 或 prune。<span id="more-525"></span></li>
</ul>
<h3>实例：</h3>
<dl>
<dt>检查健康状况并去除无用的内容 (译注：cruft 不知如此翻译是否妥当，git-gc 基本是这个含义)。</dt>
<dd>
<pre><tt>$ git fsck <strong>(1)</strong>
$ git count-objects <strong>(2)</strong>
$ git gc <strong>(3)</strong></tt></pre>
<ol>
<li>不加<tt>–full</tt>参数的情况下，这个命令一般会以非常低廉的代价确保仓库在一个不错的健康状态之中。</li>
<li>统计有多少松散的对象，没有 repack 的对象消耗了多少硬盘空间。</li>
<li>在本地仓库进行 repack，并进行其他日常维护工作。</li>
</ol>
</dd>
<dt>将一个小项目 repack 进入一个单独的 pack。</dt>
<dd>
<pre><tt>$ git gc <strong>(1)</strong></tt></pre>
<ol>
<li>将所有可以从 refs 访问到的对象都打包添加进一个 pack，然后删除其他 pack。</li>
</ol>
</dd>
</dl>
<h2>个人开发者 (独立工作)</h2>
<p>独立工作的个人开发者不需要和其他人交换补丁，在单一的仓库中独自工作，通常会用到这些命令。</p>
<ul>
<li>git-show-branch(1): 查看当前的分支位置。</li>
<li>git-log(1)：查看发生了些什么。</li>
<li>git-checkout(1) 和 git-branch(1)：在分支间切换。</li>
<li>git-add(1)：管理索引文件。</li>
<li>git-diff(1)和git-status(1)：查看正在改动些什么。</li>
<li>git-commit(1)：向前推进当前分支。</li>
<li>git-reset(1) 和 (带有路径参数的)git-checkout(1)：撤销变更。</li>
<li>git-merge(1)：合并两个本地分支。</li>
<li>git-rebase(1)：维护局部分支。<em>(译 注：git rebase 的工作大致是这样：原来在本地基于上游版本v，进行了一些改进，现在上游版本进化到了v+n，这时，在本地将基础首先进化到 v+n，然后把对 v 提交的、但还没进入 v+n 的 commit 加入到 v+n，其中可能会有冲突，这可能需要进行一些冲突处理，这里的这个在上游版本基础上添加内容而成的分支称为 topic 分支，这里翻译为局部分支。)</em></li>
<li>git-tag(1)：标记标签。</li>
</ul>
<h3>实例：</h3>
<dl>
<dt>以一个 tarball 来作为新仓库的起点。</dt>
<dd>
<pre><tt>$ tar zxf frotz.tar.gz
$ cd frotz
$ git-init
$ git add . <strong>(1)</strong>
$ git commit -m “import of frotz source tree.”
$ git tag v2.43 <strong>(2)</strong></tt></pre>
<ol>
<li>将当前目录的所有内容加入仓库。</li>
<li>添加一个轻量级的，没有注释的标签。</li>
</ol>
</dd>
<dt>简历一个局部分支并进行开发。</dt>
<dd>
<pre><tt>$ git checkout -b alsa-audio <strong>(1)</strong>
$ edit/compile/test
$ git checkout — curses/ux_audio_oss.c <strong>(2)</strong>
$ git add curses/ux_audio_alsa.c <strong>(3)</strong>
$ edit/compile/test
$ git diff HEAD <strong>(4)</strong>
$ git commit -a -s <strong>(5)</strong>
$ edit/compile/test
$ git reset –soft HEAD^ <strong>(6)</strong>
$ edit/compile/test
$ git diff ORIG_HEAD <strong>(7)</strong>
$ git commit -a -c ORIG_HEAD <strong>(8)</strong>
$ git checkout master <strong>(9)</strong>
$ git merge alsa-audio <strong>(10)</strong>
$ git log –since=’3 days ago’ <strong>(11)</strong>
$ git log v2.43.. curses/ <strong>(12)</strong></tt></pre>
<ol>
<li>创建一个新的局部分支。</li>
<li>取消对<tt>curses/ux_audio_oss.c</tt>的修改。</li>
<li>如果添加了文件的话，需要告诉 git；而删除或修改文件的话，一会的 <tt>git commit -a</tt> 就可以处理了。</li>
<li>查看将会提交哪些变更。</li>
<li>签署并提交所有你测试过的内容。</li>
<li>回到上一个 commit，但保存工作拷贝中的内容。</li>
<li>查看自从上一个我们取回的不成熟提交以来的所有变更。</li>
<li>重新进行上一步中没有完成的提交，使用你自己写的提交信息。</li>
<li>切换到 master 分支。</li>
<li>将局部分支合并入你的主分支。</li>
<li>检查提交日志；其他的可以一起用上的输出选择方式包括<tt>–max-count=10</tt> (最多显示10个commit), <tt>–until=2005-12-10</tt> 等等。</li>
<li>只查看<tt>curses/</tt> 目录中，<tt>v2.43</tt>标签以来的变更。</li>
</ol>
</dd>
</dl>
<h2>个人开发者 (参与者)</h2>
<p>在一个小组中参与协同工作的开发者需要学会下面一些命令，以和他人沟通，同时也需要独立的开发者们会用到的命令。</p>
<ul>
<li>git-clone(1)：从上游来复制出本地仓库。</li>
<li>git-pull(1) 和 git-fetch(1)：同上游保持同步更新。</li>
<li>git-push(1)：共享仓库，这是是用 CVS 风格的情况下共享仓库的方法。</li>
<li>git-format-patch(1)：准备邮件形式提交补丁，如果采用 Linux 内核风格的工作方法。</li>
</ul>
<h3>实例：</h3>
<dl>
<dt>克隆上游源，并在此基础上工作。最后，将变更送回到上游。</dt>
<dd>
<pre><tt>$ git clone git://git.kernel.org/pub/scm/…/torvalds/linux-2.6 my2.6
$ cd my2.6
$ edit/compile/test; git commit -a -s <strong>(1)</strong>
$ git format-patch origin <strong>(2)</strong>
$ git pull <strong>(3)</strong>
$ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 <strong>(4)</strong>
$ git pull git://git.kernel.org/pub/…/jgarzik/libata-dev.git ALL <strong>(5)</strong>
$ git reset –hard ORIG_HEAD <strong>(6)</strong>
$ git gc <strong>(7)</strong>
$ git fetch –tags <strong>(8)</strong></tt></pre>
<ol>
<li>若干次类似操作。</li>
<li>从本地分支输出 email 形式的补丁用于提交。</li>
<li><tt>git pull</tt>从<tt>origin</tt>取出更新并合并如当前分支。</li>
<li>取出之后，查看上次取出后上游产生的变更，只观察我们感兴趣的部分。</li>
<li>从某仓库的某分支取出变更并合并。</li>
<li>回退上一次取出的内容。</li>
<li>用垃圾回收去掉上次回退造成的残余物。</li>
<li>时常从<tt>origin</tt>取出标签信息，并放到<tt>.git/refs/tags/</tt>目录下。</li>
</ol>
</dd>
<dt>推送入另一个仓库。</dt>
<dd>
<pre><tt>satellite$ git clone mothership:frotz frotz <strong>(1)</strong>
satellite$ cd frotz
satellite$ git config –get-regexp ‘^(remote|branch).’ <strong>(2)</strong>
remote.origin.url mothership:frotz
remote.origin.fetch refs/heads/*:refs/remotes/origin/*
branch.master.remote origin
branch.master.merge refs/heads/master
satellite$ git config remote.origin.push
           master:refs/remotes/satellite/master <strong>(3)</strong>
satellite$ edit/compile/test/commit
satellite$ git push origin <strong>(4)</strong>

mothership$ cd frotz
mothership$ git checkout master
mothership$ git merge satellite/master <strong>(5)</strong></tt></pre>
<ol>
<li>mothership 主机上的你的归属目录中有一个 frotz 仓库，从那里克隆仓库到 satellite 主机上来。</li>
<li>克隆缺省会设置这些配置变量。这样，<tt>git pull</tt> 命令就会从 mothership 取出内容，并放到到本地的<tt>remotes/origin/*</tt>目录下的跟踪分支来。</li>
<li>设置<tt>git push</tt>命令将本地的<tt>master</tt>分支推送到 mothership 主机的 <tt>remotes/satellite/master</tt>分支去。</li>
<li>push 将会把我们的工作存储到 mothership 主机的 <tt>remotes/satellite/master</tt> 跟踪分支上。你可以把这作为是一种备份手段。</li>
<li>在 mothership 主机上，合并 satellite 主机上来的工作到 master 分支。</li>
</ol>
</dd>
<dt>从某个标签开始分支。</dt>
<dd>
<pre><tt>$ git checkout -b private2.6.14 v2.6.14 <strong>(1)</strong>
$ edit/compile/test; git commit -a
$ git checkout master
$ git format-patch -k -m –stdout v2.6.14..private2.6.14 |
  git am -3 -k <strong>(2)</strong></tt></pre>
<ol>
<li>基于一个众所周知的(但在什么东西后面的)标签创建一个私有分支。</li>
<li>不适用正式的 “merge”，将 <tt>private2.6.14</tt> 分支上的改动移植到 <tt>master</tt> 分支上来。</li>
</ol>
</dd>
</dl>
<h2>集成者</h2>
<p>项目中的中心人物会扮演一个集成者的角色，收集他人提供的变更，查看并集成在一起，对外发布结果。与一般参与者相比，集成者还需要用到这样一些命令。</p>
<ul>
<li>git-am(1)：应用来自各个开发者的 email 形式的补丁。</li>
<li>git-pull(1)：合并来自你信任的副手的变更。</li>
<li>git-format-patch(1)：准备并发送替换建议给贡献者们。</li>
<li>git-revert(1)：撤销修补。</li>
<li>git-push(1)：发布新的版本。</li>
</ul>
<h3>实例：</h3>
<dl>
<dt>我的典型 GIT 一天。</dt>
<dd>
<pre><tt>$ git status <strong>(1)</strong>
$ git show-branch <strong>(2)</strong>
$ mailx <strong>(3)</strong>
&amp; s 2 3 4 5 ./+to-apply
&amp; s 7 8 ./+hold-linus
&amp; q
$ git checkout -b topic/one master
$ git am -3 -i -s -u ./+to-apply <strong>(4)</strong>
$ compile/test
$ git checkout -b hold/linus &amp;&amp; git am -3 -i -s -u ./+hold-linus <strong>(5)</strong>
$ git checkout topic/one &amp;&amp; git rebase master <strong>(6)</strong>
$ git checkout pu &amp;&amp; git reset –hard next <strong>(7)</strong>
$ git merge topic/one topic/two &amp;&amp; git merge hold/linus <strong>(8)</strong>
$ git checkout maint
$ git cherry-pick master~4 <strong>(9)</strong>
$ compile/test
$ git tag -s -m “GIT 0.99.9x” v0.99.9x <strong>(10)</strong>
$ git fetch ko &amp;&amp; git show-branch master maint ‘tags/ko-*’ <strong>(11)</strong>
$ git push ko <strong>(12)</strong>
$ git push ko v0.99.9x <strong>(13)</strong></tt></pre>
<ol>
<li>查看有什么正在做、没提交的东西。</li>
<li>查看有哪些局部分支，思考他们是否成熟了。</li>
<li>阅读邮件，保存那些可以用的，也保存那些还不是很成熟的。</li>
<li>交互式打补丁，使用自己的签名。</li>
<li>如果需要，建立局部分支，并用自己的签名打补丁。</li>
<li>将内部的还没有并入 master 也没有成为稳定分支的一部分的局部分支用 rebase 移植到 master 上。</li>
<li>reset <tt>pu</tt>，让它总是从 next 开始。</li>
<li>将仍在工作中的分支们合并在一起。</li>
<li>对先前的版本进行问题修正。</li>
<li>建立一个有签名的标签。</li>
<li>确信我没有偶然将 master 退回到已经发布出去的版本的后面了。<tt>ko</tt> 是我在 kernel.org 的仓库的简写，看起来类似这样：
<pre><tt>$ cat .git/remotes/ko
URL: kernel.org:/pub/scm/git/git.git
Pull: master:refs/tags/ko-master
Pull: next:refs/tags/ko-next
Pull: maint:refs/tags/ko-maint
Push: master
Push: next
Push: +pu
Push: maint</tt></pre>
<p>在 <tt>git show-branch</tt> 的输出中, <tt>master</tt> 应该包含 <tt>ko-master</tt> 的所有内容, 而 <tt>next</tt> 应该包含<tt>ko-next</tt> 的所有内容。</li>
<li>推送出最新版本。</li>
<li>把标签也推送出去。</li>
</ol>
</dd>
</dl>
<h2>仓库管理</h2>
<p>仓库管理员会使用如下工具来设置和维护开发者们对仓库的访问方法。</p>
<ul>
<li>git-daemon(1)：允许匿名下载仓库。</li>
<li>git-shell(1) 可以被用于<em>restricted login shell</em> 来将中心仓库共享给用户。</li>
</ul>
<p>update hook howto 有一个不错的关于管理一个共享的中心仓库的例子。</p>
<h3>实例：</h3>
<dl>
<dt>我们假设如下内容位于 /etc/services 文件之内：</dt>
<dd>
<pre><tt>$ grep 9418 /etc/services
git             9418/tcp                # Git Version Control System</tt></pre>
</dd>
<dt>用 git-daemon 通过 inetd 提供 /pub/scm 服务。</dt>
<dd>
<pre><tt>$ grep git /etc/inetd.conf
git     stream  tcp     nowait  nobody
  /usr/bin/git-daemon git-daemon –inetd –export-all /pub/scm</tt></pre>
<p>实际配置文件中应该是一行。</p>
</dd>
<dt>用 git-daemon 通过 xinetd 提供 /pub/scm 服务。</dt>
<dd>
<pre><tt>$ cat /etc/xinetd.d/git-daemon
# default: off
# description: The git server offers access to git repositories
service git
{
        disable = no
        type            = UNLISTED
        port            = 9418
        socket_type     = stream
        wait            = no
        user            = nobody
        server          = /usr/bin/git-daemon
        server_args     = –inetd –export-all –base-path=/pub/scm
        log_on_failure  += USERID
}</tt></pre>
<p>设置时请参考你的 xinetd(8) 文档，上述设置适用于 Fedora 系统。其他系统可能有所不同。</p>
</dd>
<dt>仅提供 push/pull 权限给开发者。</dt>
<dd>
<pre><tt>$ grep git /etc/passwd <strong>(1)</strong>
alice:x:1000:1000::/home/alice:/usr/bin/git-shell
bob:x:1001:1001::/home/bob:/usr/bin/git-shell
cindy:x:1002:1002::/home/cindy:/usr/bin/git-shell
david:x:1003:1003::/home/david:/usr/bin/git-shell
$ grep git /etc/shells <strong>(2)</strong>
/usr/bin/git-shell</tt></pre>
<ol>
<li>将 login shell 设置为 /usr/bin/git-shell, 这样，只有<tt>git push</tt> 和 <tt>git pull</tt> 操作才被允许。用户如果要访问计算机，需要通 ssh 访问权限。</li>
<li>in many distributions /etc/shells needs to list what is used as the login shell. 很多发布版中，只有 /etc/shells 列出的程序才能作为 login shell.</li>
</ol>
</dd>
<dt>CVS 风格的共享仓库。</dt>
<dd>
<pre><tt>$ grep git /etc/group <strong>(1)</strong>
git:x:9418:alice,bob,cindy,david
$ cd /home/devo.git
$ ls -l <strong>(2)</strong>
  lrwxrwxrwx   1 david git    17 Dec  4 22:40 HEAD -&gt; refs/heads/master
  drwxrwsr-x   2 david git  4096 Dec  4 22:40 branches
  -rw-rw-r–   1 david git    84 Dec  4 22:40 config
  -rw-rw-r–   1 david git    58 Dec  4 22:40 description
  drwxrwsr-x   2 david git  4096 Dec  4 22:40 hooks
  -rw-rw-r–   1 david git 37504 Dec  4 22:40 index
  drwxrwsr-x   2 david git  4096 Dec  4 22:40 info
  drwxrwsr-x   4 david git  4096 Dec  4 22:40 objects
  drwxrwsr-x   4 david git  4096 Nov  7 14:58 refs
  drwxrwsr-x   2 david git  4096 Dec  4 22:40 remotes
$ ls -l hooks/update <strong>(3)</strong>
  -r-xr-xr-x   1 david git  3536 Dec  4 22:40 update
$ cat info/allowed-users <strong>(4)</strong>
refs/heads/master       alice|cindy
refs/heads/doc-update   bob
refs/tags/v[0-9]*       david</tt></pre>
<ol>
<li>将开发者们都放入 git 组。</li>
<li>并让整个共享仓库对组可写。</li>
<li>使用 Carl 写的 Documentation/howto 中的 update-hook 例子用于分支策略控制。</li>
<li>alice 和 cindy 可以向 master 中 push 内容，只有 bob 可以向 doc-update 中 push 内容。david 是对外发布管理员，是惟一可以创建并 push 版本标签的人。</li>
</ol>
</dd>
<dt>支持哑协议传输的 HTTP Server.</dt>
<dd>
<pre><tt>dev$ git update-server-info <strong>(1)</strong>
dev$ ftp user@isp.example.com <strong>(2)</strong>
ftp&gt; cp -r .git /home/user/myproject.git</tt></pre>
<ol>
<li>确认 info/refs 和 objects/info/packs 的内容是更新过的。</li>
<li>上传到你的 ISP 提供的公共 HTTP 服务器。</li>
</ol>
</dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/git-commonly-used-commands-525/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.211 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2025-12-28 09:30:50 -->
