1
1
[[_replace]]
2
2
=== 替换
3
3
4
- Git 对象是不可改变的,但它提供一种有趣的方式来用其他对象假替换数据库中的数个 Git 对象。
4
+ Git 对象是不可改变的,但它提供一种有趣的方式来用其他对象假装替换数据库中的 Git 对象。
5
5
6
6
7
- `replace`命令可以让你在 Git 中指定一个对象并可以声称“每次你遇到这个 Git 对象时,假装它是其他的东西”。在你的历史中替换一个已有的提交时,这是一个最常用的方法 。
7
+ `replace` 命令可以让你在 Git 中指定一个对象并可以声称“每次你遇到这个 Git 对象时,假装它是其他的东西”。在你的历史中替换一个提交为另一个时,这会非常有用 。
8
8
9
9
10
- 例如,你有一个大型的代码历史并想把自己的仓库分成一个短的历史和一个更大更长久的历史,短历史供新的开发者使用,后者给喜欢数据挖掘的人使用。你可以通过最新提交来“替换”早期提交的方式来将一个历史移植到其他历史上。这意味着你不用在新历史中真正替换每一个提交,(历史来源会影响 SHA 的值)你可以加入他们。
10
+ 例如,你有一个大型的代码历史并想把自己的仓库分成一个短的历史和一个更大更长久的历史,短历史供新的开发者使用,后者给喜欢数据挖掘的人使用。
11
+ 你可以使用最新提交来将新一条历史中的早期提交“替换”掉的方式,这种方式可以把一条历史移植到其他历史上。这意味着你不用在新历史中真正替换每一个提交,(历史来源会影响 SHA 的值)你可以加入他们。
11
12
12
13
让我们来试试吧!首先获取一个已经存在的仓库,并将其分成两个仓库,一个是最近的仓库,一个是历史版本的仓库。然我们将见证在不更改仓库 SHA 值的情况下通过`replace`命令来合并他们。
13
14
@@ -23,11 +24,11 @@ c6e1e95 fourth commit
23
24
c1822cf first commit
24
25
----
25
26
26
- 我们想将其分成拆分成两行历史。第一行作为历史版本的仓库包括第一个到第四个提交,第二行作为最近的仓库包括第四 、五个提交。
27
+ 我们想将其分成拆分成两条历史。第一条作为历史版本的仓库-包括第一个到第四个提交,第二条作为最近的仓库-包括第四 、五个提交。
27
28
28
29
image::images/replace1.png[]
29
30
30
- 创建历史版本的历史很容易,我们可以只将一个分支放入历史中,然后将这个分支推送到一个新的远程仓库的 master 分支。
31
+ 创建历史版本的历史很容易,我们可以只将一个历史中的分支推送到一个新的远程仓库的 master 分支。
31
32
32
33
[source,console]
33
34
----
58
59
* [new branch] history -> master
59
60
----
60
61
61
- 这样一来,我们的历史就发布了。稍难的部分则是截断我们最近的历史 。我们需要一个重叠以便于用一个相等的提交来替换另一个提交,这样一来,我们将截断到第四、五个提交。
62
+ 这样一来,我们的历史就发布了。稍难的部分则是截断我们最近的历史来让它变的更小 。我们需要一个重叠以便于用一个相等的提交来替换另一个提交,这样一来,我们将截断到第四、五个提交。
62
63
63
64
[source,console]
64
65
----
@@ -70,8 +71,8 @@ c6e1e95 (history) fourth commit
70
71
c1822cf first commit
71
72
----
72
73
73
- 在这个案例中,创建一个基础提交很有用,这个提交拥有如何扩展历史的命令 。这样一来,如果其他的开发者在截断的历史中命中第一个提交或需要更多提交时就知晓做什么了。
74
- 因此,接下来我们要做的是用命令创建一个最初的提交对象 ,然后在其上面变基剩下的提交(第四、五个提交)。
74
+ 在这个案例中,创建一个基础提交很有用,这个提交拥有如何扩展历史的指令 。这样一来,如果其他的开发者在截断的历史中命中第一个提交或需要更多提交时就知晓做什么了。
75
+ 因此,接下来我们要做的是用命令创建一个最初的提交对象,然后在其上面变基剩下的提交(第四、五个提交)。
75
76
76
77
为了这么做,我们需要选择一个点去拆分,对于我们而言是第三个提交( SHA 是`9c68fdc`),因此我们的提交将基于此提交树。我们可以使用`commit-tree`命令来创建基础提交,这样我们就有了一个树,并返回一个全新的、无父节点的 SHA 提交对象。
77
78
[source,console]
@@ -82,12 +83,12 @@ $ echo 'get history from blah blah blah' | git commit-tree 9c68fdc^{tree}
82
83
83
84
[NOTE]
84
85
=====
85
- `commit-tree`命令属于底层指令。有许多指令并非直接使用,而需通过其他的 Git 命令替换使用 。有时当我们做一些像这样的奇怪事情时,Git 允许我们偶尔使用这些底层的命令 。想了解更多关于底层命令的内容参见<<_plumbing_porcelain>>
86
+ `commit-tree`命令属于底层指令。有许多指令并非直接使用,而是被 **其他的** Git 命令用来做更小一些的工作 。有时当我们做一些像这样的奇怪事情时,它们允许我们做一些真的底层的东西但并不适用于日常使用 。想了解更多关于底层命令的内容参见 <<_plumbing_porcelain>>
86
87
=====
87
88
88
89
image::images/replace3.png[]
89
90
90
- 现在我们已经有一个基础提交了,我们可以通过`git rebase --onto`命令来讲其他的历史变基到基础提交之上 。`--onto`参数是刚才`commit-tree`命令返回的 SHA 值,变基点则在第三个提交 :
91
+ 现在我们已经有一个基础提交了,我们可以通过 `git rebase --onto` 命令来将剩余的历史变基到基础提交之上 。`--onto`参数是刚才`commit-tree`命令返回的 SHA 值,变基点会成为第三个提交(我们想留下的第一个提交的父提交, `9c68fdc`) :
91
92
92
93
[source,console]
93
94
----
@@ -99,9 +100,9 @@ Applying: fifth commit
99
100
100
101
image::images/replace4.png[]
101
102
102
- 我们已经用基础提交重写了最近的历史,基础提交包括如何重新组成整个历史的命令。我们可以将新历史提交到新项目中 ,当其他人克隆这个仓库时,他们仅能看到最近两次提交以及一个包含命令的的基础提交 。
103
+ 我们已经用基础提交重写了最近的历史,基础提交包括如何重新组成整个历史的命令。我们可以将新历史推送到新项目中 ,当其他人克隆这个仓库时,他们仅能看到最近两次提交以及一个包含指令的基础提交 。
103
104
104
- 现在我们将以其他人的身份来克隆这个项目。为了在克隆截断后的仓库后得到历史数据,需要添加第二个远程的历史版本库并取回 。
105
+ 现在我们将以想获得整个历史的人的身份来初次克隆这个项目。在克隆这个截断后的仓库后为了得到历史数据,需要添加第二个远程的历史版本库并抓取 。
105
106
106
107
107
108
[source,console]
@@ -120,7 +121,7 @@ From https://github.com/schacon/project-history
120
121
* [new branch] master -> project-history/master
121
122
----
122
123
123
- 现在,合作者在 `master`分支中拥有他们最近的提交并且在`project-history/master`分支中拥有过去的提交。
124
+ 现在,协作者在 `master`分支中拥有他们最近的提交并且在`project-history/master`分支中拥有过去的提交。
124
125
125
126
[source,console]
126
127
----
@@ -136,7 +137,7 @@ c6e1e95 fourth commit
136
137
c1822cf first commit
137
138
----
138
139
139
- 为了合并他们,你可以使用`git replace`命令加上你想替换的提交信息来进行替换。这样一来,我么就可以将`project-history/master`分支中的第四个提交替换为 master 分支中的第四次提交 。
140
+ 为了合并他们,你可以使用`git replace`命令加上你想替换的提交信息来进行替换。这样一来,我么就可以将 master 分支中的第四个提交替换为 `project-history/master` 分支中的第四个提交 。
140
141
141
142
[source,console]
142
143
----
@@ -155,7 +156,7 @@ e146b5f fifth commit
155
156
c1822cf first commit
156
157
----
157
158
158
- 不用改变上游的 SHA 我们就能用一个提交来替换历史中的所有不同的提交,并且所有的工具( bisect , blame 等)也都奏效。
159
+ 很酷,是不是? 不用改变上游的 SHA 我们就能用一个提交来替换历史中的所有不同的提交,并且所有的工具(\` bisect`, \` blame` 等)也都奏效。
159
160
160
161
image::images/replace5.png[]
161
162
172
173
fourth commit
173
174
----
174
175
175
- 请记住,`81a708d`真正的父提交是`622e882`提交 ,而非呈现的`9c68fdce`提交。
176
+ 请记住,`81a708d` 真正的父提交是 `622e882` 占位提交 ,而非呈现的 `9c68fdce` 提交。
176
177
177
178
另一个有趣的事情是数据将会以以下引用显示:
178
179
@@ -186,4 +187,4 @@ e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/master
186
187
c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/replace/81a708dd0e167a3f691541c7a6463343bc457040
187
188
----
188
189
189
- 这意味着可以轻而易举的和其他人分享我们的替换,正因为我们可以将替换推送到服务器中,其他人才可以下载到。也许在历史移植情况下不是很有用(既然每个人都能轻松下载到,为何还要拆分他们呢?),但是在其他情况下这种替换方式仍有其广泛的用途 。
190
+ 这意味着可以轻而易举的和其他人分享我们的替换,正因为我们可以将替换推送到服务器中,其他人才可以下载到。也许在历史移植情况下不是很有用(既然每个人都能轻松下载到,为何还要拆分他们呢?),但在其他情况下仍然很有用 。
0 commit comments