Minor editing secrets.
[gitmagic/gitmagic.git] / vi / secrets.txt
blob993c5d413fe7dd82e909cc407adac1cf7a2b3364
1 == Các Bí Mật ==
3 Chúng ta mổ xẻ để hiểu được làm thế nào mà Git có thể thi hành kỳ diệu như vậy. Tôi sẽ không thể nói quá chi tiết được. Nếu bạn muốn có được sự mô tả chỉ tiết thì hãy đọc http://www.kernel.org/pub/software/scm/git/docs/user-manual.html[sổ tay].
5 === Tính Ẩn ===
7 Git làm việc có vẻ kín đáo? Chỉ cần nói riêng về việc sử dụng lệnh commit và merge, bạn có thể làm việc mà không cần biết đến sự tồn tại của hệ thống quản lý mã nguồn. Cho đến khi bạn cần nó, và cho đến khi bạn vui sướng vì Git đã trông coi mã nguồn cho bạn trong suốt thời gian qua.
9 Các hệ thống quản lý mã nguồn khác ép buộc bạn luôn luôn phải tranh đấu với thói quan liêu. Quyền truy cập của các tệp tin có thể là chỉ cho phép đọc trừ phi bạn nói rõ với máy chủ trung tâm là các tệp tin nào bạn muốn chỉnh sửa. Tốc độ làm việc của phần lớn các lệnh sẽ tỷ lệ nghịch với số lượng người sử dụng. Mọi công việc sẽ đình trệ khi mạng máy tính hay máy chủ ngừng hoạt động.
11 Đối lập với hạn chế trên, Git đơn giản giữ lịch sử của dự án của bạn trong thư mục `.git` trong thư mục làm việc của bạn. Đây là bản sao lịch sử của riêng bạn, do vậy bạn có thể làm việc không cần mạng cho đến khi cần truyền thông với những người khác. Bạn có toàn quyền quyết định với các tệp tin của mình bởi vì Git có thể tạo lại trạng thái đã ghi lại từ `.git` bất kỳ lúc nào một cách dễ dàng.
13 === Tính Toàn vẹn ===
15 Phần lớn mọi người sử dụng phương pháp mã hóa để giữ cho thông tin của mình không bị nhòm ngó, nhưng có thứ quan trọng không kém đó là giữ cho thông tin của mình được toàn vẹn. Chính việc sử dụng hàm băm mã hóa đã làm ngăn ngừa sự sai hỏng dữ liệu do rủi ro hay ác ý.
17 Giá trị SHA1 có thể coi như là một số định danh 160-bit không trùng lắp cho mỗi chuỗi ký tự bạn dùng trong đời sống của mình. Trên thực tế nó còn làm được nhiều hơn thế: mọi chuỗi ký tự that any human will ever use over many lifetimes.
19 Bản thân giá trị SHA1 cũng là một chuỗi ký tự, chúng ta có thể băm chuỗi có chứa giá trị băm khác. This simple observation là cực kỳ hữu dụng: tra cứu 'hash chains'. Sau này chúng ta sẽ thấy làm cách nào Git sử dụng nó để mà đảm bảo tính toàn vẹn của dữ liệu.
21 Tóm lại, Git lưu giữ dữ liệu của bạn trong thư mục con `.git/objects`, thay vì sử dụng tên tệp tin như thông thường, bạn sẽ chỉ nhìn thấy ID của chúng. Bằng cách sử dụng ID để làm tên tệp tin, cũng tốt như là cách sử dụng lockfiles và timestamping, Git biến đổi bất kỳ hệ thống tệp tin thông thường bất kỳ nào thành một cơ sở dữ liệu hiệu quả và mạnh mẽ.
23 === Thông Minh===
25 Làm thể nào mà Git biết bạn đã đổi tên một tệp tin, dù là bạn chẳng bao giờ đề cập đến điều này một cách rõ ràng? Chắc chắn rồi, bạn có lẽ đã chạy lệnh *git mv*, nhưng   but that is exactly the same as a *git rm* theo sau bởi lệnh *git add*.
27 Git heuristically truy tìm renames and copies giữa các phiên bản liên tiếp. Trên thực tế, nó có thể tìm ra từng đoạn mã nguồn đã bị di chuyển hay sao chép giữa các tệp tin! Dẫu cho nó không thể it xử lý được mọi trường hợp, it does a decent job, và đặc tính này luôn luôn được phát triển. If it fails to work for you, try options enabling more expensive copy detection, và cất nhắc đến việc cập nhật.
29 === Mục Lục ===
31 Với mọi tệp tin được theo dõi, Git ghi lại các thông tin như là kích thước, thời gian tạo và lần cuối sửa đổi trong một tệp tin được biết đến là một mục lục 'index'. Để xác định rõ một tệp tin có bị thay đổi hay không, Git so sánh nó ở thời điểm hiện tại với phần lưu giữ trong bộ nhớ. Nếu chúng giống nhau, thế thì Git có thể bỏ qua việc đọc tệp tin đó lại lần nữa.
33 Since stat calls are considerably faster than file reads, nếu bạn chỉ chỉnh sửa
34 vài tệp tin, Git có thể cập nhật trạng thái của nó cực kỳ nhanh chóng.
36 We stated earlier that the index is a staging area. Why is a bunch of file
37 stats a staging area? Bởi vì lệnh add đặt các tệp tin vào trong cơ sở dữ liệu của Git
38 và cập nhật những stats này, trong lúc lệnh commit được thực hiện, mà không có tùy chọn, creates a
39 commit based only on these stats và các tệp tin đã sẵn có trong cơ sở dữ liệu.
41 === Git's Origins ===
43 http://lkml.org/lkml/2005/4/6/121[Linux Kernel Mailing List post] này miêu tả chain of events that led to Git. Toàn bộ tuyến này is a fascinating archaeological địa chỉ dành cho các sử gia Git.
45 === Đối tượng Cơ Sở Dữ Liệu ===
47 Mỗi một phiên bản của dữ liệu của bạn được giữ trong 'object database', mà nó nằm trong
48 thư mục con `.git/objects`; the other residents of `.git/` hold lesser data:
49 mục lục, tên các nhánh, các thẻ tag, các tùy chọn cấu hình, nhật ký, vị trí
50 hiện tại của location of the head commit, và những thứ tương tự như thế. The object database is elementary yet
51 elegant, và cội nguồn sức mạnh của Git.
53 Mỗi tệp tin trong `.git/objects` là một 'đối tượng'. Ở đây có 3 loại đối tượng
54 liên quan đến chúng ta: đối tượng 'blob', đối tượng cây 'tree', và đối tượng 'commit'.
56 === Blobs ===
58 Đầu tiên, hãy tạo một tệp tin bất kỳ. Đặt cho nó một cái tên, tên gì cũng được. Trong một thư mục rỗng:
60  $ echo sweet > YOUR_FILENAME
61  $ git init
62  $ git add .
63  $ find .git/objects -type f
65 Bạn sẽ thấy +.git/objects/aa/823728ea7d592acc69b36875a482cdf3fd5c8d+.
67 Làm sao mà tôi biết được tệp tin khi không thấy tên của nó? Đó là bởi vì đó là giá trị
68 băm SHA1 của:
70  "blob" SP "6" NUL "sweet" LF
72 là aa823728ea7d592acc69b36875a482cdf3fd5c8d,
73 với SP là khoảng trắng, NUL là byte có giá trị bằng 0 và LF ký tự xuống dòng. Bạn có thể xác minh lại
74 bằng lệnh sau:
76   $ printf "blob 6\000sweet\n" | sha1sum
78 Git sử dụng cách 'lấy nội dung để làm tên cho tệp tin': tệp tin không được lưu trữ như theo tên của chúng,
79 but rather by the hash of the data they contain, trong tệp tin chúng ta gọi là một 'đối tượng
80 blob'. Chúng ta có thể nghĩ giá trị băm như là một định danh duy nhất cho nội dung của tệp tin, do vậy
81 ta có tên tệp tin được định danh bởi nội dung của nó. Phần khởi đầu `blob 6` đơn thuần
82 chỉ là phần đầu bao gồm kiểu đối tượng và độ dài của nó tính bằng byte; việc làm này
83 làm đơn giản hóa việc vận hành bên trong Git.
85 Đến đây tôi có thể dễ dàng đoán được bạn nghĩ gì. Tên của tệp tin là không thích hợp:
86 only the data inside is used to construct the blob object.
88 You may be wondering what happens to identical files. Hãy thử thêm một bản sao
89 một tệp tin nào đó của bạn, với bất kỳ một cái tên nào cũng được. Nội dung của +.git/objects+ stay
90 the same no matter how many you add. Git chỉ lưu giữ dữ liệu một lần duy nhất.
92 Nhưng dẫu sao, các tệp tin nằm trong +.git/objects+ đã bị nén lại theo chuẩn zlib do vậy bạn
93 không thể xem chúng một cách trực tiếp được. Đọc chúng thông qua
94 http://www.zlib.net/zpipe.c[zpipe -d], hay gõ:
96  $ git cat-file -p aa823728ea7d592acc69b36875a482cdf3fd5c8d
98 lệnh này trình bày đối tượng được cho ở dạng dễ đọc trên màn hình.
100 === Trees ===
102 Nhưng mà tên tệp tin ở đâu? Chúng phải được lưu giữ ở đâu đó chứ.
103 Git lấy tên tệp tin trong quá trình commit:
105  $ git commit  # Type some message.
106  $ find .git/objects -type f
108 Bạn sẽ thấy 3 đối tượng. Ở thời điểm này tôi không thể nói hai tệp tin mới này là cái gì, as it partly depends on the filename you picked. We'll proceed assuming you chose ``rose''. If you didn't, you can rewrite history to make it look like you did:
110  $ git filter-branch --tree-filter 'mv YOUR_FILENAME rose'
111  $ find .git/objects -type f
113 Bây giờ bạn có lẽ nhìn thấy tệp tin
114 +.git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9+, bởi vì đây là giá trị băm
115 SHA1 của nội dung của nó:
117  "tree" SP "32" NUL "100644 rose" NUL 0xaa823728ea7d592acc69b36875a482cdf3fd5c8d
119 Xác thực tệp tin này chứa thông tin như trên bằng cách gõ:
121  $ echo 05b217bb859794d08bb9e4f7f04cbda4b207fbe9 | git cat-file --batch
123 Với lệnh zpipe, ta có thể dễ dàng xác thực một giá trị băm:
125  $ zpipe -d < .git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9 | sha1sum
127 Hash verification is trickier via cat-file because its output contains more
128 than the raw uncompressed object file.
130 Tệp tin này là một đối tượng cây 'tree': một danh sách các hàng bao gồm kiểu tệp tin,
131 tên tệp tin, và giá trị băm. Trong ví dụ của chúng ta, kiểu tệp tin là 100644, điều này
132 có nghĩa `rose` là tệp tin bình thường, và giá trị băm là một đối tượng blob mà nó chứa
133 nội dung của `rose'. Dạng tệp tin khác có thể là tệp tin thi hành, symlinks hay
134 các thư mục. Trong trường hợp cuối, giá trị băm sẽ chỉ đến đối tượng cây 'tree'.
136 Nếu bạn đã chạy lệnh filter-branch, you'll have old objects you no longer need. Mặc dù
137 chúng sẽ bị loại bỏ một cách tự động một khi thời hạn chấm dứt đã đến, chúng ta sẽ
138 xóa chúng ngay bây giờ theo cách dưới đây:
140  $ rm -r .git/refs/original
141  $ git reflog expire --expire=now --all
142  $ git prune
144 Với các dự án thật bạn nên tránh việc sử dụng lệnh như trên, làm như thế bạn
145 đã phá hủy dữ liệu sao lưu dự phòng. Nếu bạn muốn làm sạch kho chứa, cách hay nhất là tạo
146 một bản sao mới. Cũng thế, hãy cẩn thận khi thao tác trực tiếp với thư mục +.git+: điều gì xảy ra nếu một lệnh
147 Git khác cũng đang thực thi cùng lúc, hay là mất điện đột ngột?
148 Đại khái, refs có thể được xóa bằng lệnh *git update-ref -d*,
149 though usually it's safe to remove +refs/original+ bằng tay.
151 === Commits ===
153 Chúng tôi đã giảng giải cho bạn 2 trong số 3 đối tượng của Git. Cái thứ 3 chính là 'commit'. Nội dung
154 của nó buộc chặt vào phần chú thích của lần commit cũng như thời gian, ngày tháng chúng được
155 tạo ra. To match what we have here, we'll have to tweak it a little:
157  $ git commit --amend -m Shakespeare  # Thay đổi phần chú thích.
158  $ git filter-branch --env-filter 'export
159      GIT_AUTHOR_DATE="Fri 13 Feb 2009 15:31:30 -0800"
160      GIT_AUTHOR_NAME="Alice"
161      GIT_AUTHOR_EMAIL="alice@example.com"
162      GIT_COMMITTER_DATE="Fri, 13 Feb 2009 15:31:30 -0800"
163      GIT_COMMITTER_NAME="Bob"
164      GIT_COMMITTER_EMAIL="bob@example.com"'  # Rig timestamps and authors.
165  $ find .git/objects -type f
167 Bạn có thể thấy
168 +.git/objects/49/993fe130c4b3bf24857a15d7969c396b7bc187+
169 là giá trị băm SHA1 của nội dung của nó:
171  "commit 158" NUL
172  "tree 05b217bb859794d08bb9e4f7f04cbda4b207fbe9" LF
173  "author Alice <alice@example.com> 1234567890 -0800" LF
174  "committer Bob <bob@example.com> 1234567890 -0800" LF
175  LF
176  "Shakespeare" LF
178 Như ở phần trước, bạn có thể chạy lệnh zpipe hay cat-file để tự mình trông thấy.
180 Đây là lần commit đầu tiên, do vậy lần commit này không có cha, nhưng những lần commit sau
181 sẽ luôn luôn chứa it nhất là một dòng chỉ định commit cha.
183 === Indistinguishable From Magic ===
185 Bí mật của Git dường như có vẻ đơn giản. Nó giống như bạn có thể trộn lẫn cùng nhau một ít kịch bản (shell scripts) và một ít code C mà đun trong vài giờ: a melange of basic filesystem operations and SHA1 hashing, garnished with lock files and fsyncs for robustness. Trên thực tế, this accurately describes the earliest versions of Git. Tuy nhiên, apart from ingenious packing tricks to save space, and ingenious indexing tricks to save time, we now know how Git deftly changes a filesystem into a database perfect for việc quản lý mã nguồn.
187 Ví dụ, nếu một tệp tin bất kỳ nào đó trong đối tượng cơ sở dữ liệu bị sai hỏng bởi lỗi do ổ đĩa,
188 thế thì giá trị băm tương ứng của nó sẽ không đúng nữa, điều này sẽ mang lại rắc rối cho chúng ta. Bằng
189 việc băm giá trị băm của đối tượng khác, chúng ta có thể duy trì tính toàn vẹn ở tất cả các mức. Commit
190 are atomic, thật vậy đấy, a commit can never only partially record changes: we can
191 only compute the hash of a commit and store it in the database after we already
192 have stored all relevant trees, blobs and parent commits. The object
193 database is immune to unexpected interruptions such as power outages.
195 We defeat even the most devious adversaries. Suppose somebody attempts to
196 stealthily modify the contents of a file in an ancient version of a project. To
197 keep the object database looking healthy, they must also change the hash of the
198 corresponding blob object since it's now a different string of bytes. This
199 means they'll have to change the hash of any tree object referencing the file,
200 and in turn change the hash of all commit objects involving such a tree, in
201 addition to the hashes of all the descendants of these commits. This implies the
202 hash of the official head differs to that of the bad repository. By
203 following the trail of mismatching hashes we can pinpoint the mutilated file,
204 as well as the commit where it was first corrupted.
206 Nói ngắn gọn, dùng 20 byte để đại diện cho lần commit cuối là an toàn,
207 nod không thể giả mạo với kho chứa Git.
209 Đặc tính nào của Git là trứ danh nhất? Nhánh? Trộn? Hay Tags?
210 Chỉ là chi tiết. Head hiện hành được giữ trong tệp tin +.git/HEAD+,
211 mà nó có chứa giá trị băm của một đối tượng commit. Giá trị băm được cập nhật trong quá trình commit
212 cũng như là một số lệnh khác. Nhánh đại thể cũng tương tự: chúng là các tệp tin trong thư mục
213 +.git/refs/heads+. Tags cũng thế: chúng ở tại +.git/refs/tags+ nhưng chúng
214 được cập nhật bởi các lệnh khác nhau.