forked from blynn/gitmagic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
clone.txt
242 lines (151 loc) · 9.43 KB
/
clone.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
== 克隆周邊 ==
在較老一代的版本控制系統裡,checkout是獲取檔案的標準操作。你將獲得一組特定保
存狀態的檔案。
在Git和其他分散式版本控制系統裡,克隆是標準的操作。通過創建整個倉庫的克隆來
獲得檔案。或者說,你實際上把整個中心伺服器做了個鏡像。凡是主倉庫上能做的事,
你都能做。
=== 計算機間同步 ===
我可以忍受製作tar包或利用rsync來作備份和基本同步。但我有時在我筆記本上編輯,
其他時間在台式機上,而且這倆之間也許並不交互。
在一個機器上初始化一個Git倉庫並提交你的檔案。然後轉到另一台機器上:
$ git clone other.computer:/path/to/files
以創建這些檔案和Git倉庫的第二個拷貝。從現在開始,
$ git commit -a
$ git pull other.computer:/path/to/files HEAD
將把另一台機器上特定狀態的檔案“拉”到你正工作的機器上。如果你最近對同一個文
件做了有衝突的修改,Git將通知你,而你也應該在解決衝突之後再次提交。
=== 典型源碼控制 ===
為你的檔案初始化Git倉庫:
$ git init
$ git add .
$ git commit -m "Initial commit"
在中心伺服器,在某個目錄初始化一個“裸倉庫”:
$ mkdir proj.git
$ cd proj.git
$ git init --bare
$ touch proj.git/git-daemon-export-ok
如需要的話,啟動Git守護進程:
$ git daemon --detach # 它也許已經在運行了
對一些Git伺服服務,按照其指導來初始化空Git倉庫。一般是在網頁上填一個表單。
把你的項目“推”到中心伺服器:
$ git push central.server/path/to/proj.git HEAD
撿出源碼,可以鍵入:
$ git clone central.server/path/to/proj.git
做了改動之後,開發保存變更到本地:
$ git commit -a
更新到最近版本:
$ git pull
所有衝突應被處理,然後提交:
$ git commit -a
把本地改動撿入到中心倉庫:
$ git push
如果主伺服器由於其他開發的活動,有了新的變更,這個撿入會失敗,該開發應該把最
新版本拿下來,解決合併衝突,然後重試。
為使用上面pull和push命令,開發必須有SSH訪問權限。不過,通過鍵入以下命令,任何
人都可以看到源碼:
$ git clone git://central.server/path/to/proj.git
本地git協議和HTTP類似:並無安全驗證,因此任何人都能拿到項目。因此,預設情況
git協議禁止推操作。
=== 封閉源碼 ===
閉源項目不要執行touch命令,並確保你從未創建`git-daemon-export-ok`檔案。資源庫
不再可以通過git協議獲取;只有那些有SSH訪問權限的人才能看到。如果你所有的資源
庫都是封閉的,那也沒必要運行運行git守護了,因為所有溝通都走SSH。
=== 裸倉庫 ===
之所以叫裸倉庫是因為其沒有工作目錄;它只包含正常情況下隱藏在`.git`子目錄下
的檔案。換句話說,它維護項目歷史,而且從不保存任何給定版本的快照。
裸倉庫扮演的角色和中心版本控制系統中中心伺服器的角色類似:你項目的中心。開
發從其中克隆項目,撿入新近改動。典型地裸倉庫存在一個伺服器上,該伺服器除了
分散數據外並不做啥。開發活動發生在克隆上,因此中心倉庫沒有工作目錄也行。
很多Git命令在裸倉庫上失敗,除非指定倉庫路徑到環境變數`GIT_DIR`,或者指定
`--bare`選項。
=== 推還是拽 ===
為什麼我們介紹了push命令,而不是依賴熟悉的pull命令?首先,在裸倉庫上pull會
失敗:除非你必須“fetch”,一個之後我們要討論的命令。但即使我們在中心伺服器上
保持一個正常的倉庫,拽些東西進去仍然很繁瑣。我們不得不登陸伺服器先,給pull
命令我們要拽自機器的網絡地址。防火牆會阻礙,並且首先如果我們沒有到伺服器的
shell訪問怎麼辦呢?
然而,除了這個案例,我們反對推進倉庫,因為當目標有工作目錄時,困惑隨之而來。
簡短截說,學習Git的時候,只在目標是裸倉庫的時候push,否則用pull的方式。
=== 項目分叉 ===
項目走歪了嗎?或者認為你可以做得更好?那麼在伺服器上:
$ git clone git://main.server/path/to/files
之後告訴每個相關的人你伺服器上項目的分支。
在之後的時間,你可以合併來自原先項目的改變,使用命令:
$ git pull
=== 終極備份 ===
會有很多散佈在各處,禁止篡改的冗餘存檔嗎? 如果你的項目有很多開發,那乾脆啥也
別做了。你的每份代碼克隆是一個有效備份。不僅當前狀態,還包括你項目整個歷史。
感謝哈希加密算法,如果任何人的克隆被損壞,只要他們與其他的交互,這個克隆就會
被修好。
如果你的項目並不是那麼流行,那就找儘可能多的伺服來放克隆吧。
真正的偏執狂應該總是把HEAD最近20位元組的SHA1哈希值寫到安全的地方。應該保證安全,
而不是把它藏起來。比如,把它發佈到報紙上就不錯,因為對攻擊者而言,更改每份報
紙是很難的。
=== 輕快多任務 ===
比如你想並行開發多個功能。那麼提交你的項目並運行:
$ git clone . /some/new/directory
Git使用硬連結和檔案共享來儘可能安全地創建克隆,因此它一眨眼就完成了,因此你現
在可以並行操作兩個沒有相互依賴的功能。例如,你可以編輯一個克隆,同時編譯另一
個。感謝 http://en.wikipedia.org/wiki/Hard_link[hardlinking], 本地克隆比簡單
備份省時省地。
現在你可以同時工作在兩個彼此獨立的特性上。比如,你可以在編譯一個克隆的時候編
輯另一個克隆。任何時候,你都可以從其它克隆提交並拖拽變更。
$ git pull /the/other/clone HEAD
=== 游擊版本控制 ===
你正做一個使用其他版本控制系統的項目, 而你非常思念Git? 那麼在你的工作目錄初
始化一個Git倉庫:
$ git init
$ git add .
$ git commit -m "Initial commit"
然後克隆它:
$ git clone . /some/new/directory
並在這個目錄工作,按你所想在使用Git。過一會,一旦你想和其他每個人同步,在這種
情況下,轉到原來的目錄,用其他的版本控制工具同步,並鍵入:
$ git add .
$ git commit -m "Sync with everyone else"
現在轉到新目錄運行:
$ git commit -a -m "Description of my changes"
$ git pull
把你的變更提交給他人的過程依賴于其他版本控制系統。這個新目錄包含你的改動的文
件。需要運行其他版本控制系統的命令來上載這些變更到中心倉庫。
Subversion, 或許是最好的中心式版本控制系統,為無數項目所用。 *git svn* 命令為
Subversion倉庫自動化了上面的操作,並且也可以用作
http://google-opensource.blogspot.com/2008/05/export-git-project-to-google-code.html[
導出Git項目到Subversion倉庫] 的替代。
=== Mercurial ===
Mercurial是一個類似的的版本控制系統,几乎可以和Git一起無縫工作。使用
`hg-git`插件,一個Mercurial用戶可以無損地往Git倉庫推送,從Git倉庫拖拽。
使用Git獲得`hg-git`插件:
$ git clone git://github.com/schacon/hg-git.git
或使用Mercurial:
$ hg clone http://bitbucket.org/durin42/hg-git/
不好意思,我沒注意Git有類似的插件。因此, 我主張使用Git而不是Mercurial作為主資
源庫,即使你偏愛Mercurial。使用Mercurial項目,通常一個自願者維護一個平行的
Git項目以適應Git用戶,然而感謝`hg-git`插件,一個Git項目自動地適應Mercurial用
戶。
儘管該插件可以把一個Mercurial倉庫轉成一個Git倉庫,通過推到一個空的倉庫,
這個差事交給`hg-fast-export.sh`腳本還是更容易些。來自:
$ git clone git://repo.or.cz/fast-export.git
要轉化,只需在一個空目錄運行:
$ git init
$ hg-fast-export.sh -r /hg/repo
注意該腳本應加入你的`$PATH`。
=== Bazaar ===
我們簡略提一下Bazaar,它畢竟是緊跟Git和Mercurial之後最流行的自由分散式版本控
制系統。
Bazaar有後來者的優勢,它相對年輕些;它的設計者可以從前人的錯誤中學習,並且躲
過去翻歷史上犯過的錯誤。另外,它的開發人員對可移植性以及和與其它版本控制系統
的互操作性也考慮周全。
一個`bzr-git`插件讓Bazaar用戶在一定程度下可以工作在Git倉庫。`tailor`程序轉
換Bazaar倉庫到Git倉庫,並且可以遞增的方式做,要知道`bzr-fast-export`只是
在一次性轉換性情況下工作良好。
=== 我偏愛Git的原因 ===
我起先選擇Git是因為我聽說它能管理不可想象地不可管理的Linux內核源碼。我從來沒
覺得有離開的必要。Git已經服侍的很好了,並且我也沒有被其瑕疵所困擾。因為我主要
使用Linux,其他平台上的問題與我無關。
還有,我偏愛C程序和bash腳本,以及諸如Python的可執行可腳本:較少依賴,並且我也
沉迷于快速的執行時間。
我考慮過Git才能如何提高,甚至自己寫類似的工具,但只作為研究練練手。即使完成這
個項目,我也無論如何會繼續使用Git,因為使用一個古裡古怪的系統所獲甚微。
自然地,你的需求和期望可能不同,並且你可能使用另一個系統會好些。儘管如此,使
用Git你都錯不太遠。