clearly-describe-rm-mv
html 321 lines 14.1 KB
Raw
1 ---
2 layout: zh_reference
3 ---
4
5 <div class="box">
6 <h2>
7 <span class="docs">
8 <a target="new" href="http://git-scm.com/book/en/Git-Basics-Working-with-Remotes">书</a>
9 </span>
10 分享与更新项目
11 </h2>
12 <div class="block">
13 <p>
14 Git 并不像 Subversion 那样有个中心服务器。
15 目前为止所有的命令都是本地执行的,更新的知识本地的数据库。
16 要通过 Git 与其他开发者合作,你需要将数据放到一台其他开发者能够连接的服务器上。
17 Git 实现此流程的方式是将你的数据与另一个仓库同步。在服务器与客户端之间并没有实质的区别 ——
18 Git 仓库就是 Git 仓库,你可以很容易地在两者之间同步。
19 </p>
20
21 <p>
22 一旦你有了个 Git 仓库,不管它是在你自己的服务器上,或者是由 GitHub 之类的地方提供,
23 你都可以告诉 Git 推送你拥有的远端仓库还没有的数据,或者叫 Git 从别的仓库把差别取过来。
24 </p>
25
26 <p>
27 联网的时候你可以随时做这个,它并不需要对应一个 <code>commit</code> 或者别的什么。
28 一般你会本地提交几次,然后从你的项目克隆自的线上的共享仓库提取数据以保持最新,将新完成的合并到你完成的工作中去,然后推送你的改动会服务器。
29 </p>
30
31 <p class="nutshell">
32 <b>简而言之</b> 使用 <code>git fetch</code> 更新你的项目,使用 <code>git push</code> 分享你的改动。
33 你可以用 <code>git remote</code> 管理你的远程仓库。
34 </p>
35 </div>
36 </div>
37
38 <div class="box">
39 <h2>
40 <span class="docs">
41 <a target="new" href="http://git-scm.com/docs/git-remote">文档</a> &nbsp;
42 <a target="new" href="http://git-scm.com/book/en/Git-Basics-Working-with-Remotes#Showing-Your-Remotes">书</a>
43 </span>
44 <a name="remote">git remote</a>
45 <span class="desc">罗列、添加和删除远端仓库别名</span>
46 </h2>
47
48 <div class="block">
49
50 <p>不像中心化的版本控制系统(客户端与服务端很不一样),Git 仓库基本上都是一致的,并且并可以同步他们。
51 这使得拥有多个远端仓库变得容易 —— 你可以拥有一些只读的仓库,另外的一些也可写的仓库。
52 </p>
53
54 <p>
55 当你需要与远端仓库同步的时候,不需要使用它详细的链接。Git 储存了你感兴趣的远端仓库的链接的别名或者昵称。
56 你可以使用 <code>git remote</code> 命令管理这个远端仓库列表。
57 </p>
58
59 <h4>
60 git remote
61 <small>列出远端别名</small>
62 </h4>
63
64 <p>
65 如果没有任何参数,Git 会列出它存储的远端仓库别名了事。默认情况下,如果你的项目是克隆的(与本地创建一个新的相反),
66 Git 会自动将你的项目克隆自的仓库添加到列表中,并取名“origin”。
67 如果你执行时加上 <code>-v</code> 参数,你还可以看到每个别名的实际链接地址。
68 </p>
69
70 <pre>
71 <b>$ git remote</b>
72 origin
73 <b>$ git remote -v</b>
74 origin git@github.com:github/git-reference.git (fetch)
75 origin git@github.com:github/git-reference.git (push)
76 </pre>
77
78 <p>在此你看到了该链接两次,是因为 Git 允许你为每个远端仓库添加不同的推送与获取的链接,以备你读写时希望使用不同的协议。
79 </p>
80
81 <h4>
82 git remote add
83 <small>为你的项目添加一个新的远端仓库</small>
84 </h4>
85
86 <p>
87 如果你希望分享一个本地创建的仓库,或者你想要获取别人的仓库中的贡献 ——
88 如果你想要以任何方式与一个新仓库沟通,最简单的方式通常就是把它添加为一个远端仓库。
89 执行 <code>git remote add [alias] [url]</code> 就可以。
90 此命令将 <code>[url]</code> 以 <code>[alias]</code> 的别名添加为本地的远端仓库。
91 </p>
92
93 <p>
94 例如,假设我们想要与整个世界分享我们的 Hello World 程序。
95 我们可以在一台服务器上创建一个新仓库(我以 GitHub 为例子)。
96 它应该会给你一个链接,在这里就是“git@github.com:schacon/hw.git”。
97 要把它添加到我们的项目以便我们推送以及获取更新,我们可以这样:
98 </p>
99
100 <pre>
101 <b>$ git remote</b>
102 <b>$ git remote add github git@github.com:schacon/hw.git</b>
103 <b>$ git remote -v</b>
104 github git@github.com:schacon/hw.git (fetch)
105 github git@github.com:schacon/hw.git (push)
106 </pre>
107
108 <p>
109 像分支的命名一样,远端仓库的别名是强制的 —— 就像“master”,没有特别意义,但它广为使用,
110 因为 <code>git init</code> 默认用它;“origin”经常被用作远端仓库别名,就因为 <code>git clone</code>
111 默认用它作为克隆自的链接的别名。此例中,我决定给我的远端仓库取名“github”,但我叫它随便什么都可以。
112 </p>
113
114 <h4>
115 git remote rm
116 <small>删除现存的某个别名</small>
117 </h4>
118
119 <p>
120 Git addeth and Git taketh away. 如果你需要删除一个远端 —— 不再需要它了、项目已经没了,等等 —— 你可以使用 <code>git remote rm [alias]</code> 把它删掉。
121 </p>
122
123 <pre>
124 <b>$ git remote -v</b>
125 github git@github.com:schacon/hw.git (fetch)
126 github git@github.com:schacon/hw.git (push)
127 <b>$ git remote add origin git://github.com/pjhyett/hw.git</b>
128 <b>$ git remote -v</b>
129 github git@github.com:schacon/hw.git (fetch)
130 github git@github.com:schacon/hw.git (push)
131 origin git://github.com/pjhyett/hw.git (fetch)
132 origin git://github.com/pjhyett/hw.git (push)
133 <b>$ git remote rm origin</b>
134 <b>$ git remote -v</b>
135 github git@github.com:schacon/hw.git (fetch)
136 github git@github.com:schacon/hw.git (push)
137 </pre>
138
139 <p class="nutshell">
140 <b>简而言之</b> 你可以用 <code>git remote</code> 列出你的远端仓库和那些仓库的链接。
141 你可以使用 <code>git remote add</code> 添加新的远端仓库,用 <code>git remote rm</code> 删掉已存在的那些。
142 </p>
143
144 </div>
145 </div>
146
147 <div class="box">
148 <h2>
149 <span class="docs">
150 <a target="new" href="http://git-scm.com/docs/git-fetch">文档</a> &nbsp;
151 <a target="new" href="http://git-scm.com/book/en/Git-Basics-Working-with-Remotes#Fetching-and-Pulling-from-Your-Remotes">书</a>
152 </span>
153 <a name="fetch">git fetch</a>
154 <span class="desc">从远端仓库下载新分支与数据</span>
155 </h2>
156
157 <br/>
158
159 <h2>
160 <span class="docs">
161 <a target="new" href="http://git-scm.com/docs/git-pull">文档</a> &nbsp;
162 <a target="new" href="http://git-scm.com/book/en/Git-Basics-Working-with-Remotes#Fetching-and-Pulling-from-Your-Remotes">书</a>
163 </span>
164 <a name="pull">git pull</a>
165 <span class="desc">从远端仓库提取数据并尝试合并到当前分支</span>
166 </h2>
167
168 <div class="block">
169
170 <p>
171 Git 有两个命令用来从某一远端仓库更新。
172 <code>git fetch</code> 会使你与另一仓库同步,提取你本地所没有的数据,为你在同步时的该远端的每一分支提供书签。
173 这些分支被叫做“远端分支”,除了 Git 不允许你检出(切换到该分支)之外,跟本地分支没区别 ——
174 你可以将它们合并到当前分支,与其他分支作比较差异,查看那些分支的历史日志,等等。同步之后你就可以在本地操作这些。
175 </p>
176
177 <p>
178 第二个会从远端服务器提取新数据的命令是 <code>git pull</code>。
179 基本上,该命令就是在 <code>git fetch</code> 之后紧接着 <code>git merge</code> 远端分支到你所在的任意分支。
180 我个人不太喜欢这命令 —— 我更喜欢 <code>fetch</code> 和 <code>merge</code> 分开来做。少点魔法,少点问题。
181 不过,如果你喜欢这主意,你可以看一下 <code>git pull</code> 的
182 <a target="new" href="http://git-scm.com/docs/git-pull">官方文档</a>。
183 </p>
184
185 <p>
186 假设你配置好了一个远端,并且你想要提取更新,你可以首先执行 <code>git fetch [alias]</code>
187 告诉 Git 去获取它有你没有的数据,然后你可以执行 <code>git merge [alias]/[branch]</code>
188 以将服务器上的任何更新(假设有人这时候推送到服务器了)合并到你的当前分支。
189 那么,如果我是与两三个其他人合作 Hello World 项目,并且想要将我最近连接之后的所有改动拿过来,我可以这么做:
190 </p>
191
192 <pre>
193 <b>$ git fetch github</b>
194 remote: Counting objects: 4006, done.
195 remote: Compressing objects: 100% (1322/1322), done.
196 remote: Total 2783 (delta 1526), reused 2587 (delta 1387)
197 Receiving objects: 100% (2783/2783), 1.23 MiB | 10 KiB/s, done.
198 Resolving deltas: 100% (1526/1526), completed with 387 local objects.
199 From github.com:schacon/hw
200 8e29b09..c7c5a10 master -> github/master
201 0709fdc..d4ccf73 c-langs -> github/c-langs
202 6684f82..ae06d2b java -> github/java
203 * [new branch] ada -> github/ada
204 * [new branch] lisp -> github/lisp
205 </pre>
206
207 <p>
208 可以看到自从上一次与远端仓库同步以后,又新赠或更新了五个分支。
209 “ada”与“lisp”分支是新的,而“master”、“clang”与“java”分支则被更新了。
210 在此例中,我的团队在合并入主分支之前,将提议的更新推送到远端分支以审核。
211 </p>
212
213 <p>
214 你可以看到 Git 做的映射。远端仓库的主分支成为了本地的一个叫做“github/master”的分支。
215 这样我就可以执行 <code>git merge github/master</code> 将远端的主分支和并入我的本地主分支。
216 或者,我可以 <code>git log github/master ^master</code> 看看该分支上的新提交。
217 如果你的远端仓库叫做“origin”,那远端主分支就会叫做 <code>origin/master</code>。几乎所有能在本地分支上执行的命令都可以在远端分支上用。
218 </p>
219
220 <p>
221 如果你有多个远端仓库,你可以执行 <code>git fetch [alias]</code> 提取特定的远端仓库,
222 或者执行 <code>git fetch --all</code> 告诉 Git 同步所有的远端仓库。
223 </p>
224
225 <p class="nutshell">
226 <b>简而言之</b> 执行 <code>git fetch [alias]</code> 来将你的仓库与远端仓库同步,提取所有它独有的数据到本地分支以合并或者怎样。
227 </p>
228
229 </div>
230
231 </div>
232
233 <div class="box">
234 <h2>
235 <span class="docs">
236 <a target="new" href="http://git-scm.com/docs/git-push">文档</a> &nbsp;
237 <a target="new" href="http://git-scm.com/book/en/Git-Basics-Working-with-Remotes#Pushing-to-Your-Remotes">书</a>
238 </span>
239 <a name="push">git push</a>
240 <span class="desc">推送你的新分支与数据到某个远端仓库</span>
241 </h2>
242
243 <div class="block">
244 <p>
245 想要与他人分享你牛鼻的提交,你需要将改动推送到远端仓库。
246 执行 <code>git push [alias] [branch]</code>,就会将你的 [branch] 分支推送成为 [alias] 远端上的 [branch] 分支。
247 让我们试试推送我们的主分支到先前添加的“github”远端仓库上去。
248 </p>
249
250 <pre>
251 <b>$ git push github master</b>
252 Counting objects: 25, done.
253 Delta compression using up to 2 threads.
254 Compressing objects: 100% (25/25), done.
255 Writing objects: 100% (25/25), 2.43 KiB, done.
256 Total 25 (delta 4), reused 0 (delta 0)
257 To git@github.com:schacon/hw.git
258 * [new branch] master -> master
259 </pre>
260
261 <p>
262 挺简单。现在如果有人从该仓库克隆,他会得到我提交的完完全全的一份历史记录了。
263 </p>
264
265 <p>
266 如果有个像之前创建的“erlang”分支那样的主题分支,想只分享这个,该怎么办呢?你可以相应的只推送该分支。
267 </p>
268
269 <pre>
270 <b>$ git push github erlang</b>
271 Counting objects: 7, done.
272 Delta compression using up to 2 threads.
273 Compressing objects: 100% (6/6), done.
274 Writing objects: 100% (6/6), 652 bytes, done.
275 Total 6 (delta 1), reused 0 (delta 0)
276 To git@github.com:schacon/hw.git
277 * [new branch] erlang -> erlang
278 </pre>
279
280 <p>
281 现在当人们从该仓库克隆时,他们就会得到一个“erlang”分支以查阅、合并。
282 用这种方式,你可以推送任何分支到任何你有写权限的仓库。
283 如果你的分支已经在该仓库中了,它会试着去更新,如果它不再,Git 会把它加上。
284 </p>
285
286 <p>
287 最后一个当你推送到远端分支时会碰到的主要问题是,其他人在此期间也推送了的情况。
288 如果你和另一个开发者同时克隆了,又都有提交,那么当她推送后你也想推送时,默认情况下 Git 不会让你覆盖她的改动。
289 相反的,它会在你试图推送的分支上执行 <code>git log</code>,确定它能够在你的推送分支的历史记录中看到服务器分支的当前进度。
290 如果它在在你的历史记录中看不到,它就会下结论说你过时了,并打回你的推送。
291 你需要正式提取、合并,然后再次推送 —— 以确定你把她的改动也考虑在内了。
292 </p>
293
294 <p>
295 当你试图推送到某个以被更新的远端分支时,会出现下面这种情况:
296 </p>
297
298 <pre>
299 <b>$ git push github master</b>
300 To git@github.com:schacon/hw.git
301 ! [rejected] master -> master (non-fast-forward)
302 error: failed to push some refs to 'git@github.com:schacon/hw.git'
303 To prevent you from losing history, non-fast-forward updates were rejected
304 Merge the remote changes before pushing again. See the 'Note about
305 fast-forwards' section of 'git push --help' for details.
306 </pre>
307
308 <p>
309 你可以修正这个问题。执行 <code>git fetch github; git merge github/master</code>,然后再推送
310 </p>
311
312 <p class="nutshell">
313 <b>简而言之</b> 执行 <code>git push [alias] [branch]</code> 将你的本地改动推送到远端仓库。
314 如果可以的话,它会依据你的 [branch] 的样子,推送到远端的 [branch] 去。
315 如果在你上次提取、合并之后,另有人推送了,Git 服务器会拒绝你的推送,知道你是最新的为止。
316 </p>
317
318 </div>
319 </div>
320
321 <p><a href="/zh/inspect">到 检查与比较&#187;</a></p>