The SSH host key has changed on 8 April, 2022 to this one: SHA256:573uTBSeh74kvOo0HJXi5ijdzRm8me27suzNEDlGyrQ
1
0
Fork 0

Changed 您 to 你

do not use the honorific version of `you' in chinese.
indeed that was weird...
gh-pages
dotnil 10 years ago
parent 0fd9c64462
commit b7cefc43bf
  1. 100
      zh/basic/index.html
  2. 46
      zh/branching/index.html
  3. 16
      zh/creating/index.html
  4. 20
      zh/index.html
  5. 44
      zh/inspect/index.html
  6. 56
      zh/remotes/index.html

@ -11,15 +11,15 @@ layout: zh_reference
</h2>
<div class="block">
<p>
Git 的所有工作就是创建与保存您的项目的快照以及之后的快照对比等工作。本章将对有关创建与提交您的项目的快照的命令作介绍。
Git 的所有工作就是创建与保存你的项目的快照以及之后的快照对比等工作。本章将对有关创建与提交你的项目的快照的命令作介绍。
</p>
<p>
这里有个重要的概念,Git 有一个叫做“索引”的东东,有点像是您的快照的缓存区。这就使您能够从更改的文件中创建出一系列组织良好的快照,而不是一次提交所有的更改。
这里有个重要的概念,Git 有一个叫做“索引”的东东,有点像是你的快照的缓存区。这就使你能够从更改的文件中创建出一系列组织良好的快照,而不是一次提交所有的更改。
</p>
<p class="nutshell">
<strong>一言以蔽之</strong>,使用 <code>git add</code> 添加需要追踪的新文件和待提交的更改,然后使用 <code>git status</code><code>git diff</code> 查看有何改动,最后用 <code>git commit</code>您的快照记录。这就是您要用的基本流程,绝大部分时候都是这样的。
<strong>一言以蔽之</strong>,使用 <code>git add</code> 添加需要追踪的新文件和待提交的更改,然后使用 <code>git status</code><code>git diff</code> 查看有何改动,最后用 <code>git commit</code>你的快照记录。这就是你要用的基本流程,绝大部分时候都是这样的。
</p>
</div>
@ -37,7 +37,7 @@ layout: zh_reference
<div class="block">
<p>
在 Git 中,在提交您修改的文件之前,您需要把它们添加到缓存。如果该文件是新的,您可以执行 <code>git add</code> 将该文件添加到缓存,但是,即使该文件已经被追踪了 —— 也就是说,曾经提交过了 —— 你仍然需要执行 <cpde>git add</code> 将新更改的文件添加到缓存去。让我们看几个例子:
在 Git 中,在提交你修改的文件之前,你需要把它们添加到缓存。如果该文件是新的,你可以执行 <code>git add</code> 将该文件添加到缓存,但是,即使该文件已经被追踪了 —— 也就是说,曾经提交过了 —— 你仍然需要执行 <cpde>git add</code> 将新更改的文件添加到缓存去。让我们看几个例子:
</p>
<p>回到我们的 Hello World 示例,初始化该项目之后,我们就要用 <code>git add</code> 将我们的文件添加进去了。我们可以用 <code>git status</code> 看看我们的项目的当前状态。
@ -54,7 +54,7 @@ layout: zh_reference
<pre>
<b>$ git add README hello.rb</b>
</pre>
现在我们再执行 <code>git status</code>,就可以看到这俩文件已经加上去了。
<pre>
@ -64,7 +64,7 @@ layout: zh_reference
</pre>
<p class="aside">
新项目中,添加所有文件很普遍,可以在当前工作目录执行命令:<code>git add .</code>。因为 Git 会递归地将执行命令时所在的目录中的所有文件添加上去,所以如果你将当前的工作目录作为参数,它就会追踪那儿的所有文件了。如此,<code>git add .</code> 就和 <code>git add README hello.rb</code> 有一样的效果。此外,效果一致的还有 <code>git add *</code>,不过那只是因为我们这还木有子目录,不需要递归地添加新文件。
新项目中,添加所有文件很普遍,可以在当前工作目录执行命令:<code>git add .</code>。因为 Git 会递归地将执行命令时所在的目录中的所有文件添加上去,所以如果你将当前的工作目录作为参数,它就会追踪那儿的所有文件了。如此,<code>git add .</code> 就和 <code>git add README hello.rb</code> 有一样的效果。此外,效果一致的还有 <code>git add *</code>,不过那只是因为我们这还木有子目录,不需要递归地添加新文件。
</p>
<p>好了,现在我们改个文件,再跑一下 <code>git status</code>,有点古怪。</p>
@ -76,12 +76,12 @@ layout: zh_reference
</pre>
<p>
“AM” 状态的意思是,这个文件在我们将它添加到缓存之后又有改动。这意味着如果我们现在提交快照,我们记录的将是上次跑 <code>git add</code> 的时候的文件版本,而不是现在在磁盘中的这个。Git 并不认为磁盘中的文件与您想快照的文件必须是一致的 —— (如果您需要它们一致,)得用 <code>git add</code> 命令告诉它。
“AM” 状态的意思是,这个文件在我们将它添加到缓存之后又有改动。这意味着如果我们现在提交快照,我们记录的将是上次跑 <code>git add</code> 的时候的文件版本,而不是现在在磁盘中的这个。Git 并不认为磁盘中的文件与你想快照的文件必须是一致的 —— (如果你需要它们一致,)得用 <code>git add</code> 命令告诉它。
</p>
<p class="nutshell">
<strong>一言以蔽之</strong>
您要将您的修改包含在即将提交的快照里的时候,执行 <code>git add</code>。任何您没有添加的改动都不会被包含在内 —— 这意味着您可以比绝大多数其他源代码版本控制系统更精确地归置您的快照。
你要将你的修改包含在即将提交的快照里的时候,执行 <code>git add</code>。任何你没有添加的改动都不会被包含在内 —— 这意味着你可以比绝大多数其他源代码版本控制系统更精确地归置你的快照。
</p>
<p>请查看《Pro Git》中 <code>git add</code> 的 “-p” 参数,以了解更多关于提交文件的灵活性的例子。
@ -98,11 +98,11 @@ layout: zh_reference
<a target="new" href="http://progit.org/book/ch2-2.html#checking_the_status_of_your_files"></a>
</span>
<a name="status">git status</a>
<span class="desc">查看的文件在工作目录与缓存的状态</span>
<span class="desc">查看的文件在工作目录与缓存的状态</span>
</h2>
<div class="block">
<p>正如<code>git add</code> 小节中所看到的,可以执行 <code>git status</code> 命令查看的代码在缓存与当前工作目录的状态。我演示该命令的时候加了 <code>-s</code> 参数,以获得简短的结果输出。若没有这个标记,命令 <code>git status</code> 将告诉更多的提示与上下文欣喜。以下便是同样状态下,有跟没有 <code>-s</code> 参数的输出对比。简短的输出如下:
<p>正如<code>git add</code> 小节中所看到的,可以执行 <code>git status</code> 命令查看的代码在缓存与当前工作目录的状态。我演示该命令的时候加了 <code>-s</code> 参数,以获得简短的结果输出。若没有这个标记,命令 <code>git status</code> 将告诉更多的提示与上下文欣喜。以下便是同样状态下,有跟没有 <code>-s</code> 参数的输出对比。简短的输出如下:
</p>
<pre>
@ -133,10 +133,10 @@ layout: zh_reference
#
</pre>
<p>您很容易发现简短的输出看起来很紧凑。而详细输出则很有帮助,提示您可以用何种命令完成您接下来可能要做的事情。
<p>你很容易发现简短的输出看起来很紧凑。而详细输出则很有帮助,提示你可以用何种命令完成你接下来可能要做的事情。
</p>
<p>Git 还会告诉您在您上次提交之后,有哪些文件被删除、修改或者存入缓存了。</p>
<p>Git 还会告诉你在你上次提交之后,有哪些文件被删除、修改或者存入缓存了。</p>
<pre>
<b>$ git status -s</b>
@ -144,7 +144,7 @@ layout: zh_reference
<span class="red">D</span> hello.rb
</pre>
可以看到,在简短输出中,有两栏。第一栏是缓存的,第二栏则是工作目录的。所以假设临时提交了 README 文件,然后又改了些,并且没有执行 <code>git add</code>会看到这个:
可以看到,在简短输出中,有两栏。第一栏是缓存的,第二栏则是工作目录的。所以假设临时提交了 README 文件,然后又改了些,并且没有执行 <code>git add</code>会看到这个:
<pre>
<b>$ git status -s</b>
@ -153,7 +153,7 @@ layout: zh_reference
</pre>
<p class="nutshell">
<strong>一言以蔽之</strong>,执行 <code>git status</code> 以查看在上次提交之后有啥被修改或者临时提交了,从而决定自己是否需要提交一次快照,同时也能知道有什么改变被记录进去了。
<strong>一言以蔽之</strong>,执行 <code>git status</code> 以查看在上次提交之后有啥被修改或者临时提交了,从而决定自己是否需要提交一次快照,同时也能知道有什么改变被记录进去了。
</p>
</div>
@ -178,7 +178,7 @@ layout: zh_reference
<small>#尚未缓存的改动</small>
</h4>
<p>如果没有其他参数,<code>git diff</code> 会以规范化的 diff 格式(一个补丁)显示自从上次提交快照之后尚未缓存的所有更改。
<p>如果没有其他参数,<code>git diff</code> 会以规范化的 diff 格式(一个补丁)显示自从上次提交快照之后尚未缓存的所有更改。
</p>
<pre>
@ -192,16 +192,16 @@ index d62ac43..8d15d50 100644
+++ b/hello.rb</span>
<span class="lblue">@@ -1,7 +1,7 @@</span>
class HelloWorld
def self.hello
<span class="red">- puts "hello world"</span>
<span class="green">+ puts "hola mundo"</span>
end
end
</pre>
<p>所以,<code>git status</code>显示上次提交更新至后所更改或者写入缓存的改动,而 <code>git diff</code> 一行一行地显示这些改动具体是啥。通常执行完 <code>git status</code> 之后接着跑一下 <code>git diff</code> 是个好习惯。
<p>所以,<code>git status</code>显示上次提交更新至后所更改或者写入缓存的改动,而 <code>git diff</code> 一行一行地显示这些改动具体是啥。通常执行完 <code>git status</code> 之后接着跑一下 <code>git diff</code> 是个好习惯。
</p>
<h4>
@ -209,7 +209,7 @@ index d62ac43..8d15d50 100644
<small>#查看已缓存的改动</small>
</h4>
<p><code>git diff --cached</code> 命令会告诉有哪些内容已经写入缓存了。也就是说,此命令显示的是接下来要写入快照的内容。所以,如果将上述示例中的 <code>hello.rb</code> 写入缓存,因为 <code>git diff</code> 显示的是尚未缓存的改动,所以在此执行它不会显示任何信息。
<p><code>git diff --cached</code> 命令会告诉有哪些内容已经写入缓存了。也就是说,此命令显示的是接下来要写入快照的内容。所以,如果将上述示例中的 <code>hello.rb</code> 写入缓存,因为 <code>git diff</code> 显示的是尚未缓存的改动,所以在此执行它不会显示任何信息。
</p>
<pre>
@ -222,7 +222,7 @@ index d62ac43..8d15d50 100644
<b>$ </b>
</pre>
<p>如果您想看看已缓存的改动,您需要执行的是
<p>如果你想看看已缓存的改动,你需要执行的是
<code>git diff --cached</code></p>
<pre>
@ -237,12 +237,12 @@ index d62ac43..8d15d50 100644
+++ b/hello.rb</span>
<span class="lblue">@@ -1,7 +1,7 @@</span>
class HelloWorld
def self.hello
<span class="red">- puts "hello world"</span>
<span class="green">+ puts "hola mundo"</span>
end
end
</pre>
@ -251,7 +251,7 @@ index d62ac43..8d15d50 100644
<small>查看已缓存的与未缓存的所有改动</small>
</h4>
<p>如果想一并查看已缓存的与未缓存的改动,可以执行 <code>git diff HEAD</code> ——也就是说要看到的是工作目录与上一次提交的更新的区别,无视缓存。假设我们又改了些 <code>ruby.rb</code> 的内容,那缓存的与未缓存的改动我们就都有了。以上三个 <code>diff</code> 命令的结果如下:
<p>如果想一并查看已缓存的与未缓存的改动,可以执行 <code>git diff HEAD</code> ——也就是说要看到的是工作目录与上一次提交的更新的区别,无视缓存。假设我们又改了些 <code>ruby.rb</code> 的内容,那缓存的与未缓存的改动我们就都有了。以上三个 <code>diff</code> 命令的结果如下:
</p>
<pre>
<b>$ vim hello.rb </b>
@ -262,12 +262,12 @@ index 4f40006..2ae9ba4 100644
+++ b/hello.rb</span>
<span class="lblue">@@ -1,7 +1,7 @@</span>
class HelloWorld
<span class="green">+ # says hello</span>
def self.hello
puts "hola mundo"
end
end
<b>$ git diff --cached</b>
<span class="umber">diff --git a/hello.rb b/hello.rb
@ -276,12 +276,12 @@ index 2aabb6e..4f40006 100644
+++ b/hello.rb</span>
<span class="lblue">@@ -1,7 +1,7 @@</span>
class HelloWorld
def self.hello
<span class="red">- puts "hello world"</span>
<span class="green">+ puts "hola mundo"</span>
end
end
<b>$ git diff HEAD</b>
<span class="umber">diff --git a/hello.rb b/hello.rb
@ -290,13 +290,13 @@ index 2aabb6e..2ae9ba4 100644
+++ b/hello.rb</span>
<span class="lblue">@@ -1,7 +1,8 @@</span>
class HelloWorld
<span class="green">+ # says hello</span>
def self.hello
<span class="red">- puts "hello world"</span>
<span class="green">+ puts "hola mundo"</span>
end
end
</pre>
@ -307,7 +307,7 @@ index 2aabb6e..2ae9ba4 100644
<p>如果我们不想要看整个 diff 输出,但是又想比 <code>git status</code> 详细点,就可以用 <code>--stat</code> 选项。该选项使它显示摘要而非全文。上文示例在使用 <code>--stat</code> 选项时,输出如下:
</p>
<pre>
<b>$ git status -s</b>
<span class="green">M</span><span class="red">M</span> hello.rb
@ -322,7 +322,7 @@ index 2aabb6e..2ae9ba4 100644
1 files changed, 2 insertions(+), 1 deletions(-)
</pre>
<p>还可以在上述命令后面制定一个目录,从而只查看特定文件或子目录的 <code>diff</code> 输出。
<p>还可以在上述命令后面制定一个目录,从而只查看特定文件或子目录的 <code>diff</code> 输出。
</p>
@ -346,7 +346,7 @@ index 2aabb6e..2ae9ba4 100644
<div class="block">
<p>现在使用 <code>git add</code> 命令将想要快照的内容写入了缓存,执行 <code> git commit</code> 就将它实际存储快照了。Git 为您的每一个提交都记录您的名字与电子邮箱地址,所以第一步是告诉 Git 这些都是啥。
<p>现在使用 <code>git add</code> 命令将想要快照的内容写入了缓存,执行 <code> git commit</code> 就将它实际存储快照了。Git 为你的每一个提交都记录你的名字与电子邮箱地址,所以第一步是告诉 Git 这些都是啥。
</p>
<pre>
@ -375,7 +375,7 @@ index 2aabb6e..2ae9ba4 100644
nothing to commit (working directory clean)
</pre>
<p>如果漏掉了 <code>-m</code> 选项,Git 会尝试为您打开一个编辑器以填写提交信息。如果 Git 在您对它的配置中找不到相关信息,默认会打开 <code>vim</code>。屏幕会像这样:
<p>如果漏掉了 <code>-m</code> 选项,Git 会尝试为你打开一个编辑器以填写提交信息。如果 Git 在你对它的配置中找不到相关信息,默认会打开 <code>vim</code>。屏幕会像这样:
</p>
<pre>
@ -393,12 +393,12 @@ nothing to commit (working directory clean)
".git/COMMIT_EDITMSG" 9L, 257C
</pre>
<p>在此,在文件头部添加实际的提交信息。以“#”开头的行都会被无视 ——Git 将 <code> git status</code> 的输出结果放在那儿以提示都改了、缓存了啥。
<p>在此,在文件头部添加实际的提交信息。以“#”开头的行都会被无视 ——Git 将 <code> git status</code> 的输出结果放在那儿以提示都改了、缓存了啥。
</p>
<p>通常,撰写良好的提交信息是很重要的。以开放源代码项目为例,多多少少以以下格式写的提示消息是个不成文的规定:
<p>通常,撰写良好的提交信息是很重要的。以开放源代码项目为例,多多少少以以下格式写的提示消息是个不成文的规定:
</p>
<pre>
简短的关于改动的总结(25个字或者更少)
@ -429,7 +429,7 @@ nothing to commit (working directory clean)
</pre>
<p class="aside">
提交注解是很重要的。因为 Git 很大一部分能耐就是它在组织本地提交和与他人分享的弹性,它很给力地能够让您为逻辑独立的改变写三到四条提交注解,以便您的工作被同仁审阅。因为提交与推送改动是有区别的,请务必花时间将各个逻辑独立的改动放到另外一个提交,并附上一份良好的提交注解,以使与您合作的人能够方便地了解您所做的,以及您为何要这么做。
提交注解是很重要的。因为 Git 很大一部分能耐就是它在组织本地提交和与他人分享的弹性,它很给力地能够让你为逻辑独立的改变写三到四条提交注解,以便你的工作被同仁审阅。因为提交与推送改动是有区别的,请务必花时间将各个逻辑独立的改动放到另外一个提交,并附上一份良好的提交注解,以使与你合作的人能够方便地了解你所做的,以及你为何要这么做。
</p>
<h4>
@ -437,7 +437,7 @@ nothing to commit (working directory clean)
<small>自动将在提交前将已记录、修改的文件放入缓存区</small>
</h4>
<p>如果觉得 <code>git add</code> 提交缓存的流程太过繁琐,Git 也允许<code>-a</code> 选项跳过这一步。基本上这句话的意思就是,为任何已有记录的文件执行 <code>git add</code> —— 也就是说,任何在您最近的提交中已经存在,并且之后被修改的文件。这让您能够用更 Subversion 方式的流程,修改些文件,然后想要快照所有所做的改动的时候执行 <code>git commit -a</code>。不过仍然需要执行 <code>git add</code> 来添加新文件,就像 Subversion 一样。
<p>如果觉得 <code>git add</code> 提交缓存的流程太过繁琐,Git 也允许<code>-a</code> 选项跳过这一步。基本上这句话的意思就是,为任何已有记录的文件执行 <code>git add</code> —— 也就是说,任何在你最近的提交中已经存在,并且之后被修改的文件。这让你能够用更 Subversion 方式的流程,修改些文件,然后想要快照所有所做的改动的时候执行 <code>git commit -a</code>。不过仍然需要执行 <code>git add</code> 来添加新文件,就像 Subversion 一样。
</p>
<pre>
@ -458,11 +458,11 @@ nothing to commit (working directory clean)
1 files changed, 2 insertions(+), 1 deletions(-)
</pre>
<p>注意,如果不缓存改动,直接执行 <code>git commit</code>,Git 会直接给出 <code>git status</code> 命令的输出,提醒啥也没缓存。我已将该消息中的重要部分高亮,它说没有添加需要提交的缓存。如果使用 <code>-a</code>,它会缓存并提交每个改动(不含新文件)。
<p>注意,如果不缓存改动,直接执行 <code>git commit</code>,Git 会直接给出 <code>git status</code> 命令的输出,提醒啥也没缓存。我已将该消息中的重要部分高亮,它说没有添加需要提交的缓存。如果使用 <code>-a</code>,它会缓存并提交每个改动(不含新文件)。
</p>
<p>
现在就完成了整个快照的流程 ——改些文件,然后用 <code>git add</code> 将要提交的改动提交到缓存,用 <code>git status</code><code>git diff</code> 看看都改了啥,最后 <code>git commit</code> 永久地保存快照。
现在就完成了整个快照的流程 ——改些文件,然后用 <code>git add</code> 将要提交的改动提交到缓存,用 <code>git status</code><code>git diff</code> 看看都改了啥,最后 <code>git commit</code> 永久地保存快照。
</p>
<p class="nutshell">
@ -483,10 +483,10 @@ nothing to commit (working directory clean)
</h2>
<div class="block">
<p><code>git reset</code> 可能是人类写的最费解的命令了。我用 Git 有些年头了,甚至还写了本书,但有的时候还是会搞不清它会做什么。所以,我只说三个明确的,通常有用的调用。请跟我一样尽管用它 —— 因为它可以很有用。
<p><code>git reset</code> 可能是人类写的最费解的命令了。我用 Git 有些年头了,甚至还写了本书,但有的时候还是会搞不清它会做什么。所以,我只说三个明确的,通常有用的调用。请跟我一样尽管用它 —— 因为它可以很有用。
</p>
<p>在此例中,我们可以用它来将不小心缓存的东东取消缓存。假设您修改了两个文件,想要将它们记录到两个不同的提交中去。您应该缓存并提交一个,再缓存并提交另外一个。如果您不小心两个都缓存了,那要如何才能<i>取消</i>缓存呢?可以用 <code>git reset HEAD -- file</code>。技术上说,在这里不需要使用 <code>--</code> —— 它用来告诉 Git 这时已经不再列选项,剩下的是文件路径了。不过养成使用它分隔选项与路径的习惯很重要,即使在可能并不需要的时候。
<p>在此例中,我们可以用它来将不小心缓存的东东取消缓存。假设你修改了两个文件,想要将它们记录到两个不同的提交中去。你应该缓存并提交一个,再缓存并提交另外一个。如果你不小心两个都缓存了,那要如何才能<i>取消</i>缓存呢?可以用 <code>git reset HEAD -- file</code>。技术上说,在这里不需要使用 <code>--</code> —— 它用来告诉 Git 这时已经不再列选项,剩下的是文件路径了。不过养成使用它分隔选项与路径的习惯很重要,即使在可能并不需要的时候。
</p>
<p>好,让我们看看取消缓存是什么样子的。这里我们有两个最近提交之后又有所改动的文件。我们将两个都缓存,并取消缓存其中一个。
@ -509,18 +509,18 @@ M hello.rb
</pre>
<p>
现在执行 <code>git commit</code> 将只记录 <code>README</code> 文件的改动,并不含现在并不在缓存中的 <code>hello.rb</code>
现在执行 <code>git commit</code> 将只记录 <code>README</code> 文件的改动,并不含现在并不在缓存中的 <code>hello.rb</code>
</p>
<p class="aside">
如果好奇,它实际的操作是将该文件在“索引”中的校验和重置为最近一次提交中的值。<code>git add</code> 会计算一个文件的校验和,将它添加到“索引”中,而 <code>git reset HEAD</code> 将它改写回原先的,从而取消缓存。
如果好奇,它实际的操作是将该文件在“索引”中的校验和重置为最近一次提交中的值。<code>git add</code> 会计算一个文件的校验和,将它添加到“索引”中,而 <code>git reset HEAD</code> 将它改写回原先的,从而取消缓存。
</p>
<p class="tip">
如果想直接执行 <code>git unstage</code>可以在 Git 中配置个别名。执行 <code>git config --global alias.unstage "reset HEAD"</code> 即可。一旦执行完它,就可以直接用 <code>git unstage [file]</code> 作为代替了。
如果想直接执行 <code>git unstage</code>可以在 Git 中配置个别名。执行 <code>git config --global alias.unstage "reset HEAD"</code> 即可。一旦执行完它,就可以直接用 <code>git unstage [file]</code> 作为代替了。
</p>
<p>如果忘了取消缓存的命令,Git 的常规 <code>git status</code> 输出的提示会很有帮助。例如,在您有已缓存的文件时,如果您不带 <code>-s</code> 执行 <code>git status</code>,它将告诉怎样取消缓存:
<p>如果忘了取消缓存的命令,Git 的常规 <code>git status</code> 输出的提示会很有帮助。例如,在你有已缓存的文件时,如果你不带 <code>-s</code> 执行 <code>git status</code>,它将告诉怎样取消缓存:
</p>
<pre>
@ -558,16 +558,16 @@ M hello.rb
</p>
<p>
默认情况下,<code>git rm file</code> 会将文件从缓存区和的硬盘中(工作目录)删除。如果要在工作目录中留着该文件,可以使用 <code>git rm --cached</code>
默认情况下,<code>git rm file</code> 会将文件从缓存区和的硬盘中(工作目录)删除。如果要在工作目录中留着该文件,可以使用 <code>git rm --cached</code>
</p>
<h4>
git mv
<small>git rm --cached orig; mv orig new; git add new</small>
</h4>
<p>
不像绝大多数其他版本控制系统,Git 并不记录记录文件重命名。它反而只记录快照,并对比快照以找到有啥文件可能被重命名了。如果一个文件从更新中删除了,而在下次快照中新添加的另一个文件的内容与它很相似,Git 就知道这极有可能是个重命名。因此,虽然有 <code>git mv</code> 命令,但它有点多余 —— 它做得所有事情就是 <code>git rm --cached</code>,重命名磁盘上的文件,然后再执行 <code>git add</code> 把新文件添加到缓存区。并不需要用它,不过如果觉得这样容易些,尽管用吧。
不像绝大多数其他版本控制系统,Git 并不记录记录文件重命名。它反而只记录快照,并对比快照以找到有啥文件可能被重命名了。如果一个文件从更新中删除了,而在下次快照中新添加的另一个文件的内容与它很相似,Git 就知道这极有可能是个重命名。因此,虽然有 <code>git mv</code> 命令,但它有点多余 —— 它做得所有事情就是 <code>git rm --cached</code>,重命名磁盘上的文件,然后再执行 <code>git add</code> 把新文件添加到缓存区。并不需要用它,不过如果觉得这样容易些,尽管用吧。
</p>
<p class="aside">
@ -576,7 +576,7 @@ M hello.rb
<p class="nutshell">
<strong>一言以蔽之</strong>
执行 <code>git rm</code> 来删除 Git 追踪的文件。它还会删除的工作目录中的相应文件。
执行 <code>git rm</code> 来删除 Git 追踪的文件。它还会删除的工作目录中的相应文件。
</p>
</div>

@ -10,11 +10,11 @@ layout: zh_reference
分支与合并
</h2>
<div class="block">
<p>分支是我最喜欢的 Git 特性之一。如果您用过其他版本控制系统,把您所知的分支给忘记,倒可能更有帮助些 —— 事实上,以我们使用分支的方式,把 Git 的分支看作 <i>上下文</i> 反而更合适。当您检出分支时,您可以在两三个不同的分支之间来回切换。
<p>分支是我最喜欢的 Git 特性之一。如果你用过其他版本控制系统,把你所知的分支给忘记,倒可能更有帮助些 —— 事实上,以我们使用分支的方式,把 Git 的分支看作 <i>上下文</i> 反而更合适。当你检出分支时,你可以在两三个不同的分支之间来回切换。
</p>
<p class="nutshell">
<b>一言以蔽之</b>可以执行 <code>git branch (branchname)</code> 来创建分支,使用 <code>git checkout (branchname)</code> 命令切换到该分支,在该分支的上下文环境中,提交快照等,之后可以很容易地来回切换。当您切换分支的时候,Git 会用该分支的最后提交的快照替换您的工作目录的内容,所以多个分支不需要多个目录。使用 <code>git merge</code> 来合并分支。可以多次合并到统一分支,也可以选择在合并之后直接删除被并入的分支。
<b>一言以蔽之</b>可以执行 <code>git branch (branchname)</code> 来创建分支,使用 <code>git checkout (branchname)</code> 命令切换到该分支,在该分支的上下文环境中,提交快照等,之后可以很容易地来回切换。当你切换分支的时候,Git 会用该分支的最后提交的快照替换你的工作目录的内容,所以多个分支不需要多个目录。使用 <code>git merge</code> 来合并分支。可以多次合并到统一分支,也可以选择在合并之后直接删除被并入的分支。
</p>
</div>
@ -42,7 +42,7 @@ layout: zh_reference
</h2>
<div class="block">
<p><code>git branch</code> 命令是 Git 中的通用分支管理工具,可以通过它完成多项任务。我们先说会用到的最多的命令 —— 列出分支、创建分支和删除分支。我们还会介绍用来切换分支的 <code>git checkout</code> 命令。
<p><code>git branch</code> 命令是 Git 中的通用分支管理工具,可以通过它完成多项任务。我们先说会用到的最多的命令 —— 列出分支、创建分支和删除分支。我们还会介绍用来切换分支的 <code>git checkout</code> 命令。
</p>
<h4>
@ -50,7 +50,7 @@ layout: zh_reference
<small>列出可用的分支</small>
</h4>
<p>没有参数是,<code>git branch</code> 会列出您在本地的分支。您所在的分支的行首会有个星号作标记。如果您开启了<a href="http://progit.org/book/ch7-1.html#colors_in_git">彩色模式</a>,当前分支会用绿色显示。
<p>没有参数是,<code>git branch</code> 会列出你在本地的分支。你所在的分支的行首会有个星号作标记。如果你开启了<a href="http://progit.org/book/ch7-1.html#colors_in_git">彩色模式</a>,当前分支会用绿色显示。
</p>
<pre>
@ -58,7 +58,7 @@ $ git branch
* <span class="green">master</span>
</pre>
<p>此例的意思就是,我们有一个叫做“master”的分支,并且该分支是当前分支。当执行 <code>git init</code> 的时候,缺省情况下 Git 就会为您创建“master”分支。但是这名字一点特殊意味都没有 —— 事实上您并不非得要一个叫做“master”的分支。不过由于它是缺省分支名的缘故,绝大部分项目都有这个分支。
<p>此例的意思就是,我们有一个叫做“master”的分支,并且该分支是当前分支。当执行 <code>git init</code> 的时候,缺省情况下 Git 就会为你创建“master”分支。但是这名字一点特殊意味都没有 —— 事实上你并不非得要一个叫做“master”的分支。不过由于它是缺省分支名的缘故,绝大部分项目都有这个分支。
</p>
<h4>
@ -75,7 +75,7 @@ $ git branch
testing
</pre>
<p>现在我们可以看到,有了一个新分支。当以此方式在上次提交更新之后创建了新分支,如果后来又有更新提交,然后又切换到了“testing”分支,Git 将还原您的工作目录到您创建分支时候的样子 —— 您可以把它看作一个记录您当前进度的书签。让我们实际运用看看 —— 我们用 <code>git checkout (branch)</code> 切换到我们要修改的分支。
<p>现在我们可以看到,有了一个新分支。当以此方式在上次提交更新之后创建了新分支,如果后来又有更新提交,然后又切换到了“testing”分支,Git 将还原你的工作目录到你创建分支时候的样子 —— 你可以把它看作一个记录你当前进度的书签。让我们实际运用看看 —— 我们用 <code>git checkout (branch)</code> 切换到我们要修改的分支。
</p>
<pre>
@ -115,7 +115,7 @@ README hello.rb more.txt test.txt
</h4>
<p>
通常情况下,会更希望立即切换到新分支,从而在该分支中操作,然后当此分支的开发日趋稳定时,将它合并到稳定版本的分支(例如“master”)中去。执行 <code>git branch newbranch; git checkout newbranch</code> 也很简单,不过 Git 还为提供了快捷方式:<code>git checkout -b newbranch</code>
通常情况下,会更希望立即切换到新分支,从而在该分支中操作,然后当此分支的开发日趋稳定时,将它合并到稳定版本的分支(例如“master”)中去。执行 <code>git branch newbranch; git checkout newbranch</code> 也很简单,不过 Git 还为提供了快捷方式:<code>git checkout -b newbranch</code>
</p>
<pre>
@ -142,11 +142,11 @@ Switched to branch 'master'
README hello.rb more.txt test.txt
</pre>
<p>所见,我们创建了一个分支,在该分支的上下文中移除了一些文件,然后切换回我们的主分支,那些文件又回来了。使用分支将工作切分开来,从而让我们能够在不同上下文中做事,并来回切换。
<p>所见,我们创建了一个分支,在该分支的上下文中移除了一些文件,然后切换回我们的主分支,那些文件又回来了。使用分支将工作切分开来,从而让我们能够在不同上下文中做事,并来回切换。
</p>
<p>
创建新分支,在其中完成一部分工作,完成之后将它合并到主分支并删除。您会觉得这很方便,因为这么做很快很容易。如此,当您觉得这部分工作并不靠谱,舍弃它很容易。并且,如果您必须回到稳定分支做些事情,也可以很方便地这个独立分支的工作先丢在一边,完成要事之后再切换回来。
创建新分支,在其中完成一部分工作,完成之后将它合并到主分支并删除。你会觉得这很方便,因为这么做很快很容易。如此,当你觉得这部分工作并不靠谱,舍弃它很容易。并且,如果你必须回到稳定分支做些事情,也可以很方便地这个独立分支的工作先丢在一边,完成要事之后再切换回来。
</p>
<h4>
@ -180,11 +180,11 @@ Deleted branch testing (was 78b2670).
<a target="new" href="http://progit.org/book/ch3-2.html#basic_merging">book</a>
</span>
<a name="merge">git merge</a>
<span class="desc">将分支合并到的当前分支</span>
<span class="desc">将分支合并到的当前分支</span>
</h2>
<div class="block">
<p>一旦某分支有了独立内容,您终究会希望将它合并回到您的主分支。您可以使用 <code>git merge</code> 命令将任何分支合并到当前分支中去。我们那上例中的“removals”分支为例。假设我们创建了一个分支,移除了一些文件,并将它提交到该分支,其实该分支是与我们的主分支(也就是“master”)独立开来的。要想将这些移除操作包含在主分支中,可以将“removals”分支合并回去。
<p>一旦某分支有了独立内容,你终究会希望将它合并回到你的主分支。你可以使用 <code>git merge</code> 命令将任何分支合并到当前分支中去。我们那上例中的“removals”分支为例。假设我们创建了一个分支,移除了一些文件,并将它提交到该分支,其实该分支是与我们的主分支(也就是“master”)独立开来的。要想将这些移除操作包含在主分支中,可以将“removals”分支合并回去。
</p>
<pre>
@ -209,7 +209,7 @@ Fast-forward
更多复杂合并
</h4>
<p>当然,合并并不仅仅是简单的文件添加、移除的操作,Git 也会合并修改 —— 事实上,它很会合并修改。举例,我们看看在某分支中编辑某个文件,然后在另一个分支中把它的名字改掉再做些修改,最后将这俩分支合并起来。觉得会变成一坨 shi?我们试试看。
<p>当然,合并并不仅仅是简单的文件添加、移除的操作,Git 也会合并修改 —— 事实上,它很会合并修改。举例,我们看看在某分支中编辑某个文件,然后在另一个分支中把它的名字改掉再做些修改,最后将这俩分支合并起来。觉得会变成一坨 shi?我们试试看。
</p>
<pre>
@ -342,7 +342,7 @@ This project has examples of hello world in
nearly every programming language.
</pre>
<p>可以看到,Git 在产生合并冲突的地方插入了标准的与 Subversion 很像的合并冲突标记。轮到我们去解决这些冲突了。在这里我们就手动把它解决。如果要 Git 打开一个图形化的合并工具,可以看看 <a href="http://www.kernel.org/pub/software/scm/git/docs/git-mergetool.html">git 合并工具</a>(比如 kdiff3、emerge、p4merge 等)。
<p>可以看到,Git 在产生合并冲突的地方插入了标准的与 Subversion 很像的合并冲突标记。轮到我们去解决这些冲突了。在这里我们就手动把它解决。如果要 Git 打开一个图形化的合并工具,可以看看 <a href="http://www.kernel.org/pub/software/scm/git/docs/git-mergetool.html">git 合并工具</a>(比如 kdiff3、emerge、p4merge 等)。
</p>
<pre>
@ -360,7 +360,7 @@ index 9103e27,69cad1a..0000000
This project has examples of hello world in
</pre>
<p>在 Git 中,处理合并冲突的时候有个很酷的提示。如果执行 <code>git diff</code>,就像我演示的这样,它会告诉您冲突的两方,和您是如何解决的。现在是时候把它标记为已解决了。在 Git 中,我们可以用 <code>git add</code> —— 要告诉 Git 文件冲突已经解决,必须把它写入缓存区。
<p>在 Git 中,处理合并冲突的时候有个很酷的提示。如果执行 <code>git diff</code>,就像我演示的这样,它会告诉你冲突的两方,和你是如何解决的。现在是时候把它标记为已解决了。在 Git 中,我们可以用 <code>git add</code> —— 要告诉 Git 文件冲突已经解决,必须把它写入缓存区。
</p>
<pre>
@ -396,14 +396,14 @@ M README
<div class="block">
<p>
到目前为止,我们已经提交快照到项目中,在不同的各自分离的上下文中切换,但假如我们忘了自己是如何到目前这一步的那该怎么办?或者假如我们想知道此分支与彼分支到底有啥区别?Git 提供了一个告诉您使您达成当前快照的所有提交消息的工具,叫做 <code>git log</code>
到目前为止,我们已经提交快照到项目中,在不同的各自分离的上下文中切换,但假如我们忘了自己是如何到目前这一步的那该怎么办?或者假如我们想知道此分支与彼分支到底有啥区别?Git 提供了一个告诉你使你达成当前快照的所有提交消息的工具,叫做 <code>git log</code>
</p>
<p>
要理解日志(log)命令,需要了解当执行 <code>git commit</code> 以存储一个快照的时候,都有啥信息被保存了。除了文件详单、提交消息和提交者的信息,Git 还保存了您的此次提交所基于的快照。也就是,假如您克隆了一个项目,您是在什么快照的基础上做的修改而得到新保存的快照的?这有益于为项目进程提供上下文,使 Git 能够弄明白谁做了什么改动。如果 Git 有您的快照所基于的快照的话,它就能自动判断您都改变了什么。而新提交所基于的提交,被称作新提交的“父亲”。
要理解日志(log)命令,需要了解当执行 <code>git commit</code> 以存储一个快照的时候,都有啥信息被保存了。除了文件详单、提交消息和提交者的信息,Git 还保存了你的此次提交所基于的快照。也就是,假如你克隆了一个项目,你是在什么快照的基础上做的修改而得到新保存的快照的?这有益于为项目进程提供上下文,使 Git 能够弄明白谁做了什么改动。如果 Git 有你的快照所基于的快照的话,它就能自动判断你都改变了什么。而新提交所基于的提交,被称作新提交的“父亲”。
</p>
<p>某分支的按时间排序的“父亲”列表,当在该分支时,可以执行 <code>git log</code> 以查看。例如,如果我们在本章中操作的 Hello World 项目中执行 <code>git log</code>,我们可以看到已提交的消息。
<p>某分支的按时间排序的“父亲”列表,当在该分支时,可以执行 <code>git log</code> 以查看。例如,如果我们在本章中操作的 Hello World 项目中执行 <code>git log</code>,我们可以看到已提交的消息。
<pre>
<b>$ git log</b>
@ -474,7 +474,7 @@ b7ae93b added from ruby
* 17f4acf first commit
</pre>
<p>现在我们可以更清楚明了地看到何时工作分叉、又何时归并。这对查看发生了什么、应用了什么改变很有帮助,并且极大地帮助您管理您的分支。让我们创建一个分支,在里头做些事情,然后切回到主分支,也做点事情,然后看看 <code>log</code> 命令是如何帮助我们理清这俩分支上都发生了啥的。
<p>现在我们可以更清楚明了地看到何时工作分叉、又何时归并。这对查看发生了什么、应用了什么改变很有帮助,并且极大地帮助你管理你的分支。让我们创建一个分支,在里头做些事情,然后切回到主分支,也做点事情,然后看看 <code>log</code> 命令是如何帮助我们理清这俩分支上都发生了啥的。
</p>
<p>首先我们创建一个分支,来添加 Erlang 编程语言的 Hello World 示例 —— 我们想要在一个分支里头做这个,以避免让可能还不能工作的代码弄乱我们的稳定分支。这样就可以切来切去,片叶不沾身。
@ -517,7 +517,7 @@ README ruby.rb
1 files changed, 2 insertions(+), 2 deletions(-)
</pre>
<p>现在假设我们有段时间不做这个项目了,我们做别的去了。当我们回来的时候,我们想知道“erlang”分支都是啥,而主分支的进度又是怎样。仅仅看分支的名字,我们是无从知道自己还在里面有 Haskell 的改动的,但是用 <code>git log</code> 我们就可以。如果在命令行中提供一个分支名字,它就会显示该分支历史中“可及”的提交,即从该分支创立起可追溯的影响了最终的快照的提交。
<p>现在假设我们有段时间不做这个项目了,我们做别的去了。当我们回来的时候,我们想知道“erlang”分支都是啥,而主分支的进度又是怎样。仅仅看分支的名字,我们是无从知道自己还在里面有 Haskell 的改动的,但是用 <code>git log</code> 我们就可以。如果在命令行中提供一个分支名字,它就会显示该分支历史中“可及”的提交,即从该分支创立起可追溯的影响了最终的快照的提交。
</p>
<pre>
@ -551,7 +551,7 @@ ab5ab4c added erlang
</p>
<p class="nutshell">
<b>一言以蔽之</b> 使用 <code>git log</code> 列出促成当前分支目前的快照的提交历史记录。这使能够看到项目是如何到达现在的状况的。
<b>一言以蔽之</b> 使用 <code>git log</code> 列出促成当前分支目前的快照的提交历史记录。这使能够看到项目是如何到达现在的状况的。
</p>
</div>
@ -570,16 +570,16 @@ ab5ab4c added erlang
<div class="block">
<p>
如果您达到一个重要的阶段,并希望永远记住那个特别的提交快照,您可以使用 <code>git tag</code> 给它打上标签。该 <code>tag</code> 命令基本上会给该特殊提交打上永久的书签,从而使您在将来能够用它与其他提交比较。通常,您会在切取一个发布版本或者交付一些东西的时候打个标签。
如果你达到一个重要的阶段,并希望永远记住那个特别的提交快照,你可以使用 <code>git tag</code> 给它打上标签。该 <code>tag</code> 命令基本上会给该特殊提交打上永久的书签,从而使你在将来能够用它与其他提交比较。通常,你会在切取一个发布版本或者交付一些东西的时候打个标签。
</p>
<p>比如说,我们想为我们的 Hello World 项目发布一个“1.0”版本。我们可以用 <code>git tag -a v1.0</code> 命令给最新一次提交打上(<code>HEAD</code>)“v1.0”的标签。<code>-a</code> 选项意为“创建一个带注解的标签”,从而使为标签添加注解。绝大部分时候都会这么做的。不用 <code>-a</code> 选项也可以执行的,但它不会记录这标签是啥时候打的,谁打的,也不会让你添加个标签的注解。我推荐一直创建带注解的标签。</p>
<p>比如说,我们想为我们的 Hello World 项目发布一个“1.0”版本。我们可以用 <code>git tag -a v1.0</code> 命令给最新一次提交打上(<code>HEAD</code>)“v1.0”的标签。<code>-a</code> 选项意为“创建一个带注解的标签”,从而使为标签添加注解。绝大部分时候都会这么做的。不用 <code>-a</code> 选项也可以执行的,但它不会记录这标签是啥时候打的,谁打的,也不会让你添加个标签的注解。我推荐一直创建带注解的标签。</p>
<pre>
<b>$ git tag -a v1.0 </b>
</pre>
<p>执行 <code>git tag -a</code> 命令时,Git 会打开您的编辑器,让您写一句标签注解,就像您给提交写注解一样。
<p>执行 <code>git tag -a</code> 命令时,Git 会打开你的编辑器,让你写一句标签注解,就像你给提交写注解一样。
</p>
<p>现在,注意当我们执行 <code>git log --decorate</code> 时,我们可以看到我们的标签了:

@ -6,11 +6,11 @@ layout: zh_reference
<h2>获取与创建项目</h2>
<div class="block">
<p>
您得现有一个 Git 仓库,才能用它进行操作。仓库是 Git 存放您要保存的快照的数据的地方。
你得现有一个 Git 仓库,才能用它进行操作。仓库是 Git 存放你要保存的快照的数据的地方。
</p>
<p>
拥有一个 Git 仓库的途径有两种。在已有的目录中,初始化一个新的,其一。比如一个新的项目,或者一个已存在的项目,但该项目尚未有版本控制。如果想要复制一份别人的项目,或者与别人合作某个项目,也可以从一个公开的 Git 仓库克隆,其二。本章将对两者都做介绍。
拥有一个 Git 仓库的途径有两种。在已有的目录中,初始化一个新的,其一。比如一个新的项目,或者一个已存在的项目,但该项目尚未有版本控制。如果想要复制一份别人的项目,或者与别人合作某个项目,也可以从一个公开的 Git 仓库克隆,其二。本章将对两者都做介绍。
</p>
</div>
</div>
@ -41,17 +41,17 @@ Initialized empty Git repository in /opt/konichiwa/.git/
# 在 /opt/konichiwa/.git 目录初始化空 Git 仓库完毕。
</pre>
现在您可以看到在您的项目目录中有个 <code>.git</code> 的子目录。这就是您的 Git 仓库了,所有有关您的此项目的快照数据都存放在这里。
现在你可以看到在你的项目目录中有个 <code>.git</code> 的子目录。这就是你的 Git 仓库了,所有有关你的此项目的快照数据都存放在这里。
<pre>
<b>$ ls -a</b>
. .. .git README hello.rb
</pre>
恭喜,现在您就有了一个 Git 仓库的架子,可以开始快照您的项目了。
恭喜,现在你就有了一个 Git 仓库的架子,可以开始快照你的项目了。
<p class="nutshell">
<strong>一言以蔽之</strong>,用 <code>git init</code> 来在目录中创建新的 Git 仓库。可以在任何时候、任何目录中这么做,完全是本地化的。
<strong>一言以蔽之</strong>,用 <code>git init</code> 来在目录中创建新的 Git 仓库。可以在任何时候、任何目录中这么做,完全是本地化的。
</p>
</div>
@ -68,7 +68,7 @@ Initialized empty Git repository in /opt/konichiwa/.git/
</h2>
<div class="block">
<p>
如果您需要与他人合作一个项目,或者想要拷贝一个项目,看看代码,您就可以克隆那个项目。执行 <code>git clone [url]</code>,[url] 为想要拷贝的项目,就可以了。
如果你需要与他人合作一个项目,或者想要拷贝一个项目,看看代码,你就可以克隆那个项目。执行 <code>git clone [url]</code>,[url] 为想要拷贝的项目,就可以了。
</p>
<pre>
@ -85,7 +85,7 @@ README Rakefile <span class="blue">lib</span>
</pre>
<p>
上述操作将拷贝该项目的全部记录,让您本地拥有这些。并且该操作将拷贝该项目的主分支,是您能够查看代码,或编辑修改。进到该目录中,您会看到 <code>.git</code> 子目录。所有的项目数据都存在那里。
上述操作将拷贝该项目的全部记录,让你本地拥有这些。并且该操作将拷贝该项目的主分支,是你能够查看代码,或编辑修改。进到该目录中,你会看到 <code>.git</code> 子目录。所有的项目数据都存在那里。
</p>
<pre>
@ -99,7 +99,7 @@ config index <span class="blue">objects</span>
</pre>
<p>
默认情况下,Git 会按照您提供的 URL 所指示的项目的名称创建您的本地项目目录。通常就是该 URL 最后一个 <code>/</code> 之后的任何东西。如果你想要一个不一样的名字,可以在该命令后加上它,就在那个 URL 后面。
默认情况下,Git 会按照你提供的 URL 所指示的项目的名称创建你的本地项目目录。通常就是该 URL 最后一个 <code>/</code> 之后的任何东西。如果你想要一个不一样的名字,可以在该命令后加上它,就在那个 URL 后面。
</p>
<p class="nutshell">

@ -5,10 +5,10 @@ layout: zh_reference
<h2>Git 手册简介</h2>
<div class="block">
<p>
本站为 Git 参考手册。目的是为学习与记忆 Git 使用中最重要、最普遍的命令提供快速翻阅。这些命令以可能需要的操作类型划分,并且将提供日常使用中需要的一些常用的命令以及参数。
本站为 Git 参考手册。目的是为学习与记忆 Git 使用中最重要、最普遍的命令提供快速翻阅。这些命令以可能需要的操作类型划分,并且将提供日常使用中需要的一些常用的命令以及参数。
</p>
<p>
每个章节都有到下一个章节的链接,所以本手册也可以当作一个入门指导。每个页面还有一个深度 Git 文档阅读的链接,比如官方的使用手册页面或者<a href="http://progit.org">《Pro Git》</a>书中的相关章节,以便于学习了解更多的 Git 命令。首先,我们要从如何以 Git 的思维方式管理源代码开始。
每个章节都有到下一个章节的链接,所以本手册也可以当作一个入门指导。每个页面还有一个深度 Git 文档阅读的链接,比如官方的使用手册页面或者<a href="http://progit.org">《Pro Git》</a>书中的相关章节,以便于学习了解更多的 Git 命令。首先,我们要从如何以 Git 的思维方式管理源代码开始。
</p>
</div>
</div>
@ -17,27 +17,27 @@ layout: zh_reference
<h2>如何以 Git 的方式思考</h2>
<div class="block">
<p>
懂得 Git,第一件重要的事情就是要知道它与 Subversion、Perforce 或者任何您用过的版本控制工具都有着很大的差别。通常,忘掉您预想的版本控制方式,改以 Git 的方式思考,能够帮助你更好地学习 Git。
懂得 Git,第一件重要的事情就是要知道它与 Subversion、Perforce 或者任何你用过的版本控制工具都有着很大的差别。通常,忘掉你预想的版本控制方式,改以 Git 的方式思考,能够帮助你更好地学习 Git。
</p>
<p>
让我们从头开始。假设您正在设计一个新的源代码管理系统。在您使用某个工具之前,是如何完成基本的源码版本控制工作的呢?十有八九,您只是在项目到达某些阶段的时候,对项目做一份拷贝。
让我们从头开始。假设你正在设计一个新的源代码管理系统。在你使用某个工具之前,是如何完成基本的源码版本控制工作的呢?十有八九,你只是在项目到达某些阶段的时候,对项目做一份拷贝。
</p>
<pre> $ cp -R project project.bak </pre>
<p>
这样,就可以在事情变得一团糟的时候很方便的返回到之前的状态,或者通过对比当前的项目与之前的拷贝,看看自己在之后的工作中,都做了哪些修改。
这样,就可以在事情变得一团糟的时候很方便的返回到之前的状态,或者通过对比当前的项目与之前的拷贝,看看自己在之后的工作中,都做了哪些修改。
</p>
<p>
如果您有点偏执,您可能会经常作上面说的事情,或许还会给项目拷贝加个日期:
如果你有点偏执,你可能会经常作上面说的事情,或许还会给项目拷贝加个日期:
</p>
<pre> $ cp -R project project.2010-06-01.bak </pre>
<p>
如此,您就有了一堆项目在各个阶段的快照,来作比较、查看。使用这种模式,您还可以有效地与人分享项目变更。如果您会在项目到达一定阶段的时候给它打个包,丢到自己的网站上,那其他的开发者们,就能很方便地下载它,做点改动,并给你补丁回馈。
如此,你就有了一堆项目在各个阶段的快照,来作比较、查看。使用这种模式,你还可以有效地与人分享项目变更。如果你会在项目到达一定阶段的时候给它打个包,丢到自己的网站上,那其他的开发者们,就能很方便地下载它,做点改动,并给你补丁回馈。
</p>
<pre>
@ -50,7 +50,7 @@ layout: zh_reference
$ (email change.patch)</pre>
<p>
以此方式,原先的开发者就能将其他人的改动应用到他的项目中去,其他开发者也能了解做的变更。其实这便是许多开源项目采用过多年的协作方式。
以此方式,原先的开发者就能将其他人的改动应用到他的项目中去,其他开发者也能了解做的变更。其实这便是许多开源项目采用过多年的协作方式。
</p>
<p>
@ -58,13 +58,13 @@ layout: zh_reference
</p>
<p>
这就是 Git 的精要所在。通过 <code>git commit</code>告诉 Git 您想保存一份项目快照,Git 就会为您的项目中的各个文件的当前状态存一份记录。之后,绝大部分的 Git 命令都围绕这些记录展开。比如查看它们的区别(diff),提取它们的内容,等等。
这就是 Git 的精要所在。通过 <code>git commit</code>告诉 Git 你想保存一份项目快照,Git 就会为你的项目中的各个文件的当前状态存一份记录。之后,绝大部分的 Git 命令都围绕这些记录展开。比如查看它们的区别(diff),提取它们的内容,等等。
</p>
<center><img src="./images/snapshots.png"/></center>
<p>
如果可以将 Git 看作一个排序、对比以及合并项目更新的工具,那就容易理解状况和正确做事了。
如果可以将 Git 看作一个排序、对比以及合并项目更新的工具,那就容易理解状况和正确做事了。
</p>
</div>

@ -11,11 +11,11 @@ layout: zh_reference
</h2>
<div class="block">
<p>
现在有了一堆分支,短期的主题、长期的特性或者其它。怎样追踪他们呢?Git 有一组工具,可以帮助弄明白工作是在哪儿完成的,两个分支间的区别是啥,等等。
现在有了一堆分支,短期的主题、长期的特性或者其它。怎样追踪他们呢?Git 有一组工具,可以帮助弄明白工作是在哪儿完成的,两个分支间的区别是啥,等等。
</p>
<p class="nutshell">
<b>一言以蔽之</b> 执行 <code>git log</code> 找到的项目历史中的特定提交 —— 按作者、日期、内容或者历史记录。执行 <code>git diff</code> 比较历史记录中的两个不同的点 —— 通常是为了看看两个分支有啥区别,或者从某个版本到另一个版本,的软件都有啥变化。
<b>一言以蔽之</b> 执行 <code>git log</code> 找到的项目历史中的特定提交 —— 按作者、日期、内容或者历史记录。执行 <code>git diff</code> 比较历史记录中的两个不同的点 —— 通常是为了看看两个分支有啥区别,或者从某个版本到另一个版本,的软件都有啥变化。
</p>
</div>
</div>
@ -27,12 +27,12 @@ layout: zh_reference
<a target="new" href="http://progit.org/book/ch2-3.html">书k</a>
</span>
<a name="log">git log</a>
<span class="desc">过滤的提交历史记录</span>
<span class="desc">过滤的提交历史记录</span>
</h2>
<div class="block">
<p>
通过查看分支中另一分支看不到的提交记录,我们已经看到如何用 <code>git log</code> 来比较分支。(如果不记得了,它看起来是这样的:<code>git log branchA ^branchB</code>)。而且,也可以用 <code>git log</code> 去寻找特定的提交。在此,我们会看到一些更广为使用的 <code>git log</code> 选项,不过哪有很多。完整的清单可以看看官方文档。
通过查看分支中另一分支看不到的提交记录,我们已经看到如何用 <code>git log</code> 来比较分支。(如果不记得了,它看起来是这样的:<code>git log branchA ^branchB</code>)。而且,也可以用 <code>git log</code> 去寻找特定的提交。在此,我们会看到一些更广为使用的 <code>git log</code> 选项,不过哪有很多。完整的清单可以看看官方文档。
</p>
<h4>
@ -41,7 +41,7 @@ layout: zh_reference
</h4>
<p>
要过滤您的提交历史,只寻找某个特定作者的提交,您可以使用 <code>--author</code> 选项。例如,比方说我们要找 Git 源码中 Linus 提交的部分。我们可以执行类似 <code>git log --author=Linus</code> 的命令。这个查找是大小写敏感的,并且也会检索电子邮箱地址。我在此例中使用 <code>-[number]</code> 选项,以限制结果为最近 [number] 次的提交。
要过滤你的提交历史,只寻找某个特定作者的提交,你可以使用 <code>--author</code> 选项。例如,比方说我们要找 Git 源码中 Linus 提交的部分。我们可以执行类似 <code>git log --author=Linus</code> 的命令。这个查找是大小写敏感的,并且也会检索电子邮箱地址。我在此例中使用 <code>-[number]</code> 选项,以限制结果为最近 [number] 次的提交。
</p>
<pre>
@ -59,7 +59,7 @@ b532581 make "git unpack-file" a built-in
</h4>
<p>
如果您要指定一个您感兴趣的日期范围以过滤您的提交,可以执行几个选项 —— 我用 <code>--since</code><code>--before</code>,但是也可以用 <code>--until</code><code>--after</code>。例如,如果我要看 Git 项目中三周前且在四月十八日之后的所有提交,我可以执行这个(我还用了 <code>--no-merges</code> 选项以隐藏合并提交):
如果你要指定一个你感兴趣的日期范围以过滤你的提交,可以执行几个选项 —— 我用 <code>--since</code><code>--before</code>,但是也可以用 <code>--until</code><code>--after</code>。例如,如果我要看 Git 项目中三周前且在四月十八日之后的所有提交,我可以执行这个(我还用了 <code>--no-merges</code> 选项以隐藏合并提交):
</p>
<pre>
@ -81,7 +81,7 @@ b6c8d2d Documentation/remote-helpers: Add invocation section
</h4>
<p>
或许还想根据提交注释中的某个特定短语查找提交记录。可以用 <code>--grep</code> 选项。比如说我知道有个提交是有关使用 P4EDITOR 环境变量,又想回忆起那个改动是啥样子的 —— 我可以用 <code>--grep</code> 选项找到该提交。
或许还想根据提交注释中的某个特定短语查找提交记录。可以用 <code>--grep</code> 选项。比如说我知道有个提交是有关使用 P4EDITOR 环境变量,又想回忆起那个改动是啥样子的 —— 我可以用 <code>--grep</code> 选项找到该提交。
</p>
<pre>
@ -101,7 +101,7 @@ Date: Wed Mar 12 19:03:24 2008 -0500
</pre>
<p>
Git 会对所有的 <code>--grep</code><code>--author</code> 参数作逻辑或。如果<code>--grep</code><code>--author</code> 时,想看的是某人写作的并且有某个特殊的注释内容的提交记录,需要加上 <code>--all-match</code> 选项。在这些例子中,我会用上 <code>--format</code> 选项,这样我们就可以看到每个提交的作者是谁了。
Git 会对所有的 <code>--grep</code><code>--author</code> 参数作逻辑或。如果<code>--grep</code><code>--author</code> 时,想看的是某人写作的并且有某个特殊的注释内容的提交记录,需要加上 <code>--all-match</code> 选项。在这些例子中,我会用上 <code>--format</code> 选项,这样我们就可以看到每个提交的作者是谁了。
</p>
<p>
@ -151,7 +151,7 @@ e96e400 Simon Hausmann git-p4: Fix submit user-interface.
</h4>
<p>
如果您写的提交注释都极度糟糕怎么办?或者,如果您要找某个函数是何时引入的,某些变量是在哪里开始被使用的?您可以告诉 Git 在每个提交之间的差值中查找特定字符串。例如,如果我们想要找出哪个提交修改出了类似函数名“userformat_find_requirements”,我们可以执行(注意在“-S”与要找的东东之间没有“=”):
如果你写的提交注释都极度糟糕怎么办?或者,如果你要找某个函数是何时引入的,某些变量是在哪里开始被使用的?你可以告诉 Git 在每个提交之间的差值中查找特定字符串。例如,如果我们想要找出哪个提交修改出了类似函数名“userformat_find_requirements”,我们可以执行(注意在“-S”与要找的东东之间没有“=”):
</p>
<pre>
@ -180,7 +180,7 @@ Date: Tue Apr 13 22:31:12 2010 +0200
</h4>
<p>
每个提交都是项目的一个快照。由于每个提交都记录它所基于的快照,Git 能够经常对它们求差值,并以补丁形式向您展示。这意味着,对任意提交,您都可以获取该提交给项目引入补丁。您可以用 <code>git show [SHA]</code> 加上某个特定的提交 SHA 获取,或者执行 <code>git log -p</code>,它会告诉 Git 输出每个提交之后的补丁。这是个总结某一分支或者两个提交之间都发生了神马的好途径。
每个提交都是项目的一个快照。由于每个提交都记录它所基于的快照,Git 能够经常对它们求差值,并以补丁形式向你展示。这意味着,对任意提交,你都可以获取该提交给项目引入补丁。你可以用 <code>git show [SHA]</code> 加上某个特定的提交 SHA 获取,或者执行 <code>git log -p</code>,它会告诉 Git 输出每个提交之后的补丁。这是个总结某一分支或者两个提交之间都发生了神马的好途径。
</p>
<pre>
@ -234,7 +234,7 @@ index d053cc8..9103e27 100644
</h4>
<p>
如果 <code>-p</code> 选项对您来说太详细了,您可以用 <code>--stat</code> 总结这些改动。这是不用 <code>-p</code>,而用 <code>--stat</code> 选项时,同一份日志的输出。
如果 <code>-p</code> 选项对你来说太详细了,你可以用 <code>--stat</code> 总结这些改动。这是不用 <code>-p</code>,而用 <code>--stat</code> 选项时,同一份日志的输出。
</p>
<pre>
@ -259,7 +259,7 @@ Date: Fri Jun 4 12:58:53 2010 +0200
</pre>
<p>
同样的基本信息,但更紧凑 —— 它仍然让看到相对改动,和改动了哪些文件。
同样的基本信息,但更紧凑 —— 它仍然让看到相对改动,和改动了哪些文件。
</p>
</div>
@ -278,11 +278,11 @@ Date: Fri Jun 4 12:58:53 2010 +0200
<div class="block">
<p>
最后,要查看两个提交快照的绝对改动,可以用 <code>git diff</code> 命令。这在两个主要情况中广为使用 —— 查看两个分支彼此之间的差值,和查看自发布或者某个旧历史点之后都有啥变了。让我们看看这俩情况。
最后,要查看两个提交快照的绝对改动,可以用 <code>git diff</code> 命令。这在两个主要情况中广为使用 —— 查看两个分支彼此之间的差值,和查看自发布或者某个旧历史点之后都有啥变了。让我们看看这俩情况。
</p>
<p>
仅需执行 <code>git diff [version]</code>(或者给该发布打的任何标签)就可以查看自最近发布之后的改动。例如,如果我们想要看看自 v0.9 发布之后我们的项目改变了啥,我们可以执行 <code>git diff v0.9</code>
仅需执行 <code>git diff [version]</code>(或者给该发布打的任何标签)就可以查看自最近发布之后的改动。例如,如果我们想要看看自 v0.9 发布之后我们的项目改变了啥,我们可以执行 <code>git diff v0.9</code>
</p>
<pre>
@ -314,7 +314,7 @@ index bb86f00..192151c 100644
</pre>
<p>
正如 <code>git log</code>可以给它加上 <code>--stat</code> 参数。
正如 <code>git log</code>可以给它加上 <code>--stat</code> 参数。
</p>
<pre>
@ -325,7 +325,7 @@ index bb86f00..192151c 100644
</pre>
<p>
要比较两个不同的分支,可以执行类似 <code>git diff branchA branchB</code> 的命令。不过它的问题在于它会完完全全按您说的作 —— 它会直接给您个补丁文件,该补丁能够将甲分支的最新快照变成乙分支的最新快照的样子。这意味着如果两个分支已经产生分歧 —— 奔往两个不同方向了 —— 它会移除甲分支中引入的所有工作,然后累加乙分支中的所有工作。这大概不是您要的吧 —— 您想要不在甲分支中的乙分支的改动。所以您真的需要的是两个分支叉开去时,和最新的乙分支的差别。所以,如果我们的历史记录看起来像这样:
要比较两个不同的分支,可以执行类似 <code>git diff branchA branchB</code> 的命令。不过它的问题在于它会完完全全按你说的作 —— 它会直接给你个补丁文件,该补丁能够将甲分支的最新快照变成乙分支的最新快照的样子。这意味着如果两个分支已经产生分歧 —— 奔往两个不同方向了 —— 它会移除甲分支中引入的所有工作,然后累加乙分支中的所有工作。这大概不是你要的吧 —— 你想要不在甲分支中的乙分支的改动。所以你真的需要的是两个分支叉开去时,和最新的乙分支的差别。所以,如果我们的历史记录看起来像这样:
</p>
<pre>
@ -351,7 +351,7 @@ index bb86f00..192151c 100644
</pre>
<p>
可以看到,它加上了 erlang 和 haskell 文件,这确实是我们在该分支中做的,但是它同时恢复了我们在主分支中改动的 ruby 文件。我们真心想要的只是“erlang”分支中的改动(添加两个文件)。我们可以通过求两个分支分歧时的共同提交与该分支的差值得到想要的结果:
可以看到,它加上了 erlang 和 haskell 文件,这确实是我们在该分支中做的,但是它同时恢复了我们在主分支中改动的 ruby 文件。我们真心想要的只是“erlang”分支中的改动(添加两个文件)。我们可以通过求两个分支分歧时的共同提交与该分支的差值得到想要的结果:
</p>
<pre>
@ -362,7 +362,7 @@ index bb86f00..192151c 100644
</pre>
<p>
这才是我们在找的,但是我们可不想要每次都要找出两个分支分歧时的那次提交。幸运的是,Git 为此提供了一个快捷方式。如果执行 <code>git diff master...erlang</code>(在分支名之间有三个半角的点),Git 就会自动找出两个分支的共同提交(也被成为合并基础),并求差值。
这才是我们在找的,但是我们可不想要每次都要找出两个分支分歧时的那次提交。幸运的是,Git 为此提供了一个快捷方式。如果执行 <code>git diff master...erlang</code>(在分支名之间有三个半角的点),Git 就会自动找出两个分支的共同提交(也被成为合并基础),并求差值。
</p>
<pre>
@ -378,11 +378,11 @@ index bb86f00..192151c 100644
</pre>
<p>
几乎每一次您要对比两个分支的时候,您都会想用三个点的语法,因为它通常会给您您想要的。
几乎每一次你要对比两个分支的时候,你都会想用三个点的语法,因为它通常会给你你想要的。
</p>
<p>
顺带提一句,还可以让 Git 手工计算两次提交的合并基础(第一个共同的祖提交),即 <code>git merge-base</code> 命令:
顺带提一句,还可以让 Git 手工计算两次提交的合并基础(第一个共同的祖提交),即 <code>git merge-base</code> 命令:
</p>
<pre>
@ -391,7 +391,7 @@ index bb86f00..192151c 100644
</pre>
<p>
所以执行下面这个也跟 <code>git diff master...erlang</code> 一样:
所以执行下面这个也跟 <code>git diff master...erlang</code> 一样:
</p>
<pre>
@ -411,5 +411,5 @@ index bb86f00..192151c 100644
</div>
</div>
<p>就是这样了! 请阅读
<p>就是这样了! 请阅读
<a href="http://progit.org">《Pro Git》</a> 以获得更多信息。</p>

@ -11,19 +11,19 @@ layout: zh_reference
</h2>
<div class="block">
<p>
Git 并不像 Subversion 那样有个中心服务器。目前为止所有的命令都是本地执行的,更新的知识本地的数据库。要通过 Git 与其他开发者合作,需要将数据放到一台其他开发者能够连接的服务器上。Git 实现此流程的方式是将的数据与另一个仓库同步。在服务器与客户端之间并没有实质的区别 —— Git 仓库就是 Git 仓库,可以很容易地在两者之间同步。
Git 并不像 Subversion 那样有个中心服务器。目前为止所有的命令都是本地执行的,更新的知识本地的数据库。要通过 Git 与其他开发者合作,需要将数据放到一台其他开发者能够连接的服务器上。Git 实现此流程的方式是将的数据与另一个仓库同步。在服务器与客户端之间并没有实质的区别 —— Git 仓库就是 Git 仓库,可以很容易地在两者之间同步。
</p>
<p>
一旦您有了个 Git 仓库,不管它是在您自己的服务器上,或者是由 GitHub 之类的地方提供,您都可以告诉 Git 推送您拥有的远端仓库还没有的数据,或者叫 Git 从别的仓库把差别取过来。
一旦你有了个 Git 仓库,不管它是在你自己的服务器上,或者是由 GitHub 之类的地方提供,你都可以告诉 Git 推送你拥有的远端仓库还没有的数据,或者叫 Git 从别的仓库把差别取过来。
</p>
<p>
联网的时候可以随时做这个,它并不需要对应一个 <code>commit</code> 或者别的什么。一般您会本地提交几次,然后从您的项目克隆自的线上的共享仓库提取数据以保持最新,将新完成的合并到您完成的工作中去,然后推送您的改动会服务器。
联网的时候可以随时做这个,它并不需要对应一个 <code>commit</code> 或者别的什么。一般你会本地提交几次,然后从你的项目克隆自的线上的共享仓库提取数据以保持最新,将新完成的合并到你完成的工作中去,然后推送你的改动会服务器。
</p>
<p class="nutshell">
<b>一言以蔽之</b> 使用 <code>git fetch</code> 更新的项目,使用 <code>git push</code> 分享您的改动。您可以用 <code>git remote</code> 管理的远程仓库。
<b>一言以蔽之</b> 使用 <code>git fetch</code> 更新的项目,使用 <code>git push</code> 分享你的改动。你可以用 <code>git remote</code> 管理的远程仓库。
</p>
</div>
</div>
@ -40,11 +40,11 @@ layout: zh_reference
<div class="block">
<p>不像中心化的版本控制系统(客户端与服务端很不一样),Git 仓库基本上都是一致的,并且并可以同步他们。这使得拥有多个远端仓库变得容易 —— 可以可以拥有一些只读的仓库,另外的一些也可写的仓库。
<p>不像中心化的版本控制系统(客户端与服务端很不一样),Git 仓库基本上都是一致的,并且并可以同步他们。这使得拥有多个远端仓库变得容易 —— 可以可以拥有一些只读的仓库,另外的一些也可写的仓库。
</p>
<p>
您需要与远端仓库同步的时候,不需要使用它详细的链接。Git 储存了您感兴趣的远端仓库的链接的别名或者昵称。您可以使用 <code>git remote</code> 命令管理这个远端仓库列表。
你需要与远端仓库同步的时候,不需要使用它详细的链接。Git 储存了你感兴趣的远端仓库的链接的别名或者昵称。你可以使用 <code>git remote</code> 命令管理这个远端仓库列表。
</p>
<h4>
@ -53,7 +53,7 @@ layout: zh_reference
</h4>
<p>
如果没有任何参数,Git 会列出它存储的远端仓库别名了事。默认情况下,如果您的项目是克隆的(与本地创建一个新的相反),Git 会自动将您的项目克隆自的仓库添加到列表中,并取名“origin”。如果您执行时加上 <code>-v</code> 参数,还可以看到每个别名的实际链接地址。
如果没有任何参数,Git 会列出它存储的远端仓库别名了事。默认情况下,如果你的项目是克隆的(与本地创建一个新的相反),Git 会自动将你的项目克隆自的仓库添加到列表中,并取名“origin”。如果你执行时加上 <code>-v</code> 参数,还可以看到每个别名的实际链接地址。
</p>
<pre>
@ -64,20 +64,20 @@ origin git@github.com:schacon/git-reference.git (fetch)
origin git@github.com:schacon/git-reference.git (push)
</pre>
<p>在此您看到了该链接两次,是因为 Git 允许您为每个远端仓库添加不同的推送与获取的链接,以备您读写时希望使用不同的协议。
</p>
<p>在此你看到了该链接两次,是因为 Git 允许你为每个远端仓库添加不同的推送与获取的链接,以备你读写时希望使用不同的协议。
</p>
<h4>
git remote add
<small>的项目添加一个新的远端仓库</small>
<small>的项目添加一个新的远端仓库</small>
</h4>
<p>
如果您希望分享一个本地创建的仓库,或者您想要获取别人的仓库中的贡献 —— 如果您想要以任何方式与一个新仓库沟通,最简单的方式通常就是把它添加为一个远端仓库。执行 <code>git remote add [alias] [url]</code> 就可以。此命令将 <code>[url]</code><code>[alias]</code> 的别名添加为本地的远端仓库。
如果你希望分享一个本地创建的仓库,或者你想要获取别人的仓库中的贡献 —— 如果你想要以任何方式与一个新仓库沟通,最简单的方式通常就是把它添加为一个远端仓库。执行 <code>git remote add [alias] [url]</code> 就可以。此命令将 <code>[url]</code><code>[alias]</code> 的别名添加为本地的远端仓库。
</p>
<p>
例如,假设我们想要与整个世界分享我们的 Hello World 程序。我们可以在一台服务器上创建一个新仓库(我以 GitHub 为例子)。它应该会给一个链接,在这里就是“git@github.com:schacon/hw.git”。要把它添加到我们的项目以便我们推送以及获取更新,我们可以这样:
例如,假设我们想要与整个世界分享我们的 Hello World 程序。我们可以在一台服务器上创建一个新仓库(我以 GitHub 为例子)。它应该会给一个链接,在这里就是“git@github.com:schacon/hw.git”。要把它添加到我们的项目以便我们推送以及获取更新,我们可以这样:
</p>
<pre>
@ -98,7 +98,7 @@ github git@github.com:schacon/hw.git (push)
</h4>
<p>
Git addeth and Git taketh away. 如果您需要删除一个远端 —— 不再需要它了、项目已经没了,等等 —— 您可以使用 <code>git remote rm [alias]</code> 把它删掉。
Git addeth and Git taketh away. 如果你需要删除一个远端 —— 不再需要它了、项目已经没了,等等 —— 你可以使用 <code>git remote rm [alias]</code> 把它删掉。
</p>
<pre>
@ -118,7 +118,7 @@ github git@github.com:schacon/hw.git (push)
</pre>
<p class="nutshell">
<b>一言以蔽之</b> 可以用 <code>git remote</code> 列出您的远端仓库和那些仓库的链接。您可以使用 <code>git remote add</code> 添加新的远端仓库,用 <code>git remote rm</code> 删掉已存在的那些。
<b>一言以蔽之</b> 可以用 <code>git remote</code> 列出你的远端仓库和那些仓库的链接。你可以使用 <code>git remote add</code> 添加新的远端仓库,用 <code>git remote rm</code> 删掉已存在的那些。
</p>
</div>
@ -148,15 +148,15 @@ github git@github.com:schacon/hw.git (push)
<div class="block">
<p>
Git 有两个命令用来从某一远端仓库更新。<code>git fetch</code> 会使您与另一仓库同步,提取您本地所没有的数据,为您在同步时的该远端的每一分支提供书签。这些分支被叫做“远端分支”,除了 Git 不允许您检出(切换到该分支)之外,跟本地分支没区别 —— 您可以将它们合并到当前分支,与其他分支作比较差异,查看那些分支的历史日志,等等。同步之后就可以在本地操作这些。
Git 有两个命令用来从某一远端仓库更新。<code>git fetch</code> 会使你与另一仓库同步,提取你本地所没有的数据,为你在同步时的该远端的每一分支提供书签。这些分支被叫做“远端分支”,除了 Git 不允许你检出(切换到该分支)之外,跟本地分支没区别 —— 你可以将它们合并到当前分支,与其他分支作比较差异,查看那些分支的历史日志,等等。同步之后就可以在本地操作这些。
</p>
<p>
第二个会从远端服务器提取新数据的命令是 <code>git pull</code>。基本上,该命令就是在 <code>git fetch</code> 之后紧接着 <code>git merge</code> 远端分支到所在的任意分支。我个人不太喜欢这命令 —— 我更喜欢 <code>fetch</code><code>merge</code> 分开来做。少点魔法,少点问题。不过,如果您喜欢这主意,您可以看一下 <code>git pull</code><a target="new" href="http://www.kernel.org/pub/software/scm/git/docs/git-pull.html">官方文档</a>
第二个会从远端服务器提取新数据的命令是 <code>git pull</code>。基本上,该命令就是在 <code>git fetch</code> 之后紧接着 <code>git merge</code> 远端分支到所在的任意分支。我个人不太喜欢这命令 —— 我更喜欢 <code>fetch</code><code>merge</code> 分开来做。少点魔法,少点问题。不过,如果你喜欢这主意,你可以看一下 <code>git pull</code><a target="new" href="http://www.kernel.org/pub/software/scm/git/docs/git-pull.html">官方文档</a>
</p>
<p>
假设您配置好了一个远端,并且您想要提取更新,您可以首先执行 <code>git fetch [alias]</code> 告诉 Git 去获取它有您没有的数据,然后您可以执行 <code>git merge [alias]/[branch]</code> 以将服务器上的任何更新(假设有人这时候推送到服务器了)合并到的当前分支。那么,如果我是与两三个其他人合作 Hello World 项目,并且想要将我最近连接之后的所有改动拿过来,我可以这么做:
假设你配置好了一个远端,并且你想要提取更新,你可以首先执行 <code>git fetch [alias]</code> 告诉 Git 去获取它有你没有的数据,然后你可以执行 <code>git merge [alias]/[branch]</code> 以将服务器上的任何更新(假设有人这时候推送到服务器了)合并到的当前分支。那么,如果我是与两三个其他人合作 Hello World 项目,并且想要将我最近连接之后的所有改动拿过来,我可以这么做:
</p>
<pre>
@ -178,15 +178,15 @@ From github.com:schacon/hw
可以看到自从上一次与远端仓库同步以后,又新赠或更新了五个分支。“ada”与“lisp”分支是新的,而“master”、“clang”与“java”分支则被更新了。在此例中,我的团队在合并入主分支之前,将提议的更新推送到远端分支以审核。
</p>
<p>可以看到 Git 做的映射。远端仓库的主分支成为了本地的一个叫做“github/master”的分支。这样我就可以执行 <code>git merge github/master</code> 将远端的主分支和并入我的本地主分支。或者,我可以 <code>git log github/master ^master</code> 看看该分支上的新提交。如果的远端仓库叫做“origin”,那远端主分支就会叫做 <code>origin/master</code>。几乎所有能在本地分支上执行的命令都可以在远端分支上用。
<p>可以看到 Git 做的映射。远端仓库的主分支成为了本地的一个叫做“github/master”的分支。这样我就可以执行 <code>git merge github/master</code> 将远端的主分支和并入我的本地主分支。或者,我可以 <code>git log github/master ^master</code> 看看该分支上的新提交。如果的远端仓库叫做“origin”,那远端主分支就会叫做 <code>origin/master</code>。几乎所有能在本地分支上执行的命令都可以在远端分支上用。
</p>
<p>
如果您有多个远端仓库,您可以执行 <code>git fetch [alias]</code> 提取特定的远端仓库,或者执行 <code>git fetch --all</code> 告诉 Git 同步所有的远端仓库。
如果你有多个远端仓库,你可以执行 <code>git fetch [alias]</code> 提取特定的远端仓库,或者执行 <code>git fetch --all</code> 告诉 Git 同步所有的远端仓库。
</p>
<p class="nutshell">
<b>一言以蔽之</b> 执行 <code>git fetch [alias]</code> 来将的仓库与远端仓库同步,提取所有它独有的数据到本地分支以合并或者怎样。
<b>一言以蔽之</b> 执行 <code>git fetch [alias]</code> 来将的仓库与远端仓库同步,提取所有它独有的数据到本地分支以合并或者怎样。
</p>
</div>
@ -200,12 +200,12 @@ From github.com:schacon/hw
<a target="new" href="http://progit.org/book/ch2-5.html#pushing_to_your_remotes"></a>
</span>
<a name="push">git push</a>
<span class="desc">推送的新分支与数据到某个远端仓库</span>
<span class="desc">推送的新分支与数据到某个远端仓库</span>
</h2>
<div class="block">
<p>
想要与他人分享您牛鼻的提交,您需要将改动推送到远端仓库。执行 <code>git push [alias] [branch]</code>,就会将的 [branch] 分支推送成为 [alias] 远端上的 [branch] 分支。让我们试试推送我们的主分支到先前添加的“github”远端仓库上去。
想要与他人分享你牛鼻的提交,你需要将改动推送到远端仓库。执行 <code>git push [alias] [branch]</code>,就会将的 [branch] 分支推送成为 [alias] 远端上的 [branch] 分支。让我们试试推送我们的主分支到先前添加的“github”远端仓库上去。
</p>
<pre>
@ -224,7 +224,7 @@ To git@github.com:schacon/hw.git
</p>
<p>
如果有个像之前创建的“erlang”分支那样的主题分支,想只分享这个,该怎么办呢?可以相应的只推送该分支。
如果有个像之前创建的“erlang”分支那样的主题分支,想只分享这个,该怎么办呢?可以相应的只推送该分支。
</p>
<pre>
@ -239,15 +239,15 @@ To git@github.com:schacon/hw.git
</pre>
<p>
现在当人们从该仓库克隆时,他们就会得到一个“erlang”分支以查阅、合并。用这种方式,您可以推送任何分支到任何您有写权限的仓库。如果您的分支已经在该仓库中了,它会试着去更新,如果它不再,Git 会把它加上。
现在当人们从该仓库克隆时,他们就会得到一个“erlang”分支以查阅、合并。用这种方式,你可以推送任何分支到任何你有写权限的仓库。如果你的分支已经在该仓库中了,它会试着去更新,如果它不再,Git 会把它加上。
</p>
<p>
最后一个当推送到远端分支时会碰到的主要问题是,其他人在此期间也推送了的情况。如果您和另一个开发者同时克隆了,又都有提交,那么当她推送后您也想推送时,默认情况下 Git 不会让您覆盖她的改动。相反的,它会在您试图推送的分支上执行 <code>git log</code>,确定它能够在您的推送分支的历史记录中看到服务器分支的当前进度。如果它在在您的历史记录中看不到,它就会下结论说您过时了,并打回您的推送。您需要正式提取、合并,然后再次推送 —— 以确定您把她的改动也考虑在内了。
最后一个当推送到远端分支时会碰到的主要问题是,其他人在此期间也推送了的情况。如果你和另一个开发者同时克隆了,又都有提交,那么当她推送后你也想推送时,默认情况下 Git 不会让你覆盖她的改动。相反的,它会在你试图推送的分支上执行 <code>git log</code>,确定它能够在你的推送分支的历史记录中看到服务器分支的当前进度。如果它在在你的历史记录中看不到,它就会下结论说你过时了,并打回你的推送。你需要正式提取、合并,然后再次推送 —— 以确定你把她的改动也考虑在内了。
</p>
<p>
试图推送到某个以被更新的远端分支时,会出现下面这种情况:
试图推送到某个以被更新的远端分支时,会出现下面这种情况:
</p>
<pre>
@ -261,11 +261,11 @@ fast-forwards' section of 'git push --help' for details.
</pre>
<p>
可以修正这个问题。执行 <code>git fetch github; git merge github/master</code>,然后再推送
可以修正这个问题。执行 <code>git fetch github; git merge github/master</code>,然后再推送
</p>
<p class="nutshell">
<b>一言以蔽之</b> 执行 <code>git push [alias] [branch]</code>您的本地改动推送到远端仓库。如果可以的话,它会依据您的 [branch] 的样子,推送到远端的 [branch] 去。如果在您上次提取、合并之后,另有人推送了,Git 服务器会拒绝您的推送,知道您是最新的为止。
<b>一言以蔽之</b> 执行 <code>git push [alias] [branch]</code>你的本地改动推送到远端仓库。如果可以的话,它会依据你的 [branch] 的样子,推送到远端的 [branch] 去。如果在你上次提取、合并之后,另有人推送了,Git 服务器会拒绝你的推送,知道你是最新的为止。
</p>
</div>

Loading…
Cancel
Save