l10n: vi: Update Vietnamese translation:
[gitmagic.git] / vi / history.txt
blob70dcf33a5dd8627dce42f8d6d1f6260e6b70254c
1 == Bài Học về Lịch Sử ==
3 Một hệ quả tất yếu của đặc tính phân tán của Git là việc lịch sử có thể biên soạn lại một cách
4 dễ dàng. Nhưng nếu bạn xáo trộn quá khứ, hãy cẩn thận: chỉ biên soạn lại các phần trong lịch sử
5 chỉ khi bạn sở hữu nó một mình. Cũng giống như việc các quốc gia tranh cãi không kết thúc xem ai là người
6 tận tâm, hành động nào là tàn ác, nếu một người khác có một bản sao mà lịch sử của nó lại khác với
7 cái của bạn, bạn sẽ gặp rắc rối ngay khi cần tương tác với họ.
9 Một số nhà phát triển phần mềm quả quyết rằng lịch sử không thể thay đổi, tất cả mọi thứ.
10 Một số khác lại cho rằng chỉnh sửa lại cấu trúc trước khi phát hành nó ra
11 đại chúng. Git chấp nhận cả hai quan điểm. Giống như việc nhân bản, tạo nhánh và hòa trộn,
12 viết lại lịch sử đơn giản chỉ là một quyền lực mà Git trao cho bạn. Bạn có thể làm thế
13 nếu muốn.
15 === Dừng Lại Sửa Chữa ===
17 Bạn vừa mới commit, nhưng lại ước rằng mình đã gõ những dòng chú thích có nội dung khác phải không? Thế thì hãy chạy:
19  $ git commit --amend
21 để thay đổi chú thích cuối cùng. Bạn giật mình vì quên thêm các tệp tin vào? Chạy lệnh *git add* để
22 thêm nó vào, và sau đó lại chạy lệnh ở trên.
24 Bạn muốn thêm vài chỉnh sửa vào lần cuối mình đã commit ư? Thế thì cứ sửa chúng đi và sau đó chạy lệnh:
26  $ git commit --amend -a
28 === ... Và Sau đó là Nhiều Lần ===
30 Giả sử vấn đề trục trặc ở lần commit cách đây mười lần. Sau một buổi làm việc dài, bạn đã
31 tạo ra hàng tá các lần commit. Nhưng bạn không hoàn toàn hài lòng với cách mà chúng được
32 tổ chức, và một số lần commit cần được soạn lại phần mô tả. Thế thì hãy gõ:
34  $ git rebase -i HEAD~10
36 và 10 lần commit cuối sẽ xuất hiện trong $EDITOR yêu thích của bạn. Dưới đây là một đoạn trích ví dụ:
38     pick 5c6eb73 Added repo.or.cz link
39     pick a311a64 Reordered analogies in "Work How You Want"
40     pick 100834f Added push target to Makefile
42 Lần commit cũ đứng trước lần mới hơn trong danh sách, không giống như kết quả khi chạy lệnh `log`.
43 Ở đây, 5c6eb73 là lần commit cũ nhất, và 100834f là mới nhất. Thế thì:
45 - Xóa bỏ các lần commit bằng cách xóa các dòng tương ứng. Giống như lệnh revert, nhưng không
46 ghi biên bản: nó sẽ coi như là lần commit đó chưa từng bao giờ tồn tại.
47 - Đặt lại thứ tự các lần commit bằng cách thay đổi thứ tự các dòng.
48 - Thay thế `pick` bằng:
49    * `edit` để đánh dấu lần commit đó là dành cho việc tu bổ.
50    * `reword` để thay đổi phần chú giải.
51    * `squash` để hòa trộn với lần commit trước.
52    * `fixup` để hòa trộn với lần commit trước và bỏ qua việc ghi lại phần chú giải.
54 Ví dụ, chúng ta chẳng hạn thay thế `pick` ở dòng thứ hai bằng `squash`:
56     pick 5c6eb73 Added repo.or.cz link
57     squash a311a64 Reordered analogies in "Work How You Want"
58     pick 100834f Added push target to Makefile
60 Sau đó chúng ta ghi lại thay đổi và thoát ra. Git trộn lần a311a64 vào 5c6eb73. Vì vậy *squash* trộn
61 với lần kế trước nó: có thể nghĩ đây là quá trình ``nén dữ liệu''.
63 Hơn thế nữa, Git sau đó tổ hợp nhật ký của chúng và hiện tại và chỉnh sửa lại. Lệnh
64 *fixup* bỏ qua bước này; việc sửa nhật ký đơn giản là bỏ qua.
66 Nếu bạn đánh dấu một lần commit bằng *edit*, Git đưa bạn trở lại quá khứ, tới lần
67 commit lâu nhất đó. Bạn có thể tu bổ một lần commit cũ như đã mô tả ở phần trên,
68 và thậm chí tạo ra các lần commit mới ở chỗ này. Một khi bạn đã hài lòng với việc
69 ``retcon'', hãy chạy 'cỗ máy thời gian' bằng cách chạy lệnh:
71  $ git rebase --continue
73 Git sửa commits cho tới *edit* kế tiếp, hoặc tới hiện tại nếu không còn việc gì cần phải làm.
75 Bạn còn có thể bãi bỏ việc rebase bằng lệnh:
77  $ git rebase --abort
79 Do vậy cứ commit thoải mái và thường xuyên bởi vì bạn có thể dọn dẹp cho gọn gàng sau này bằng lệnh rebase.
81 === Thay Đổi Riêng Sắp Xếp Sau ===
83 Bạn đang làm việc trên một dự án đang hoạt động. Bạn đã tạo ra một số lần commit tại máy tính của mình, và
84 sau đó bạn đồng bộ hóa với cây chính thức bằng cách hòa trộn. Chu kỳ này tự lặp chính nó một số lần trước khi bạn thực sự push tới cây trên máy chủ trung tâm.
86 Nhưng hiện tại lịch sử bản sao Git trên máy tính của bạn là một mớ hỗn độn của những lần thay đổi trên máy tính riêng và máy chính thức. Bạn muốn thấy tất cả các thay đổi của riêng mình trong một đoạn liên tục không ngắt quãng, và sau tất cả các thay đổi từ kho chính thức.
88 Đây chính là công việc dành cho lệnh *git rebase* đã được miêu tả ở trên. Trong nhiều trường hợp bạn có thể sử dụng
89 cờ *--onto* và tránh xa sự tương tác với các máy tính khác.
91 Xem thêm trong *git help rebase* để thấy được chi tiết các ví dụ dành cho lệnh đáng kinh ngạc này. Bạn có thể chia cắt các lần commit. Bạn còn có thể xắp xếp lại các nhánh của một cấu trúc cây.
93 Hãy cẩn thận: rebase là một lệnh mạnh mẽ. Với những lần rebases phức tạp, trước hết hãy tạo ra
94 một bản sao lưu dự phòng bằng lệnh *git clone*.
96 === Viết Lại Lịch Sử ===
98 Thỉnh thoảng, bạn muốn việc quản lý mã nguồn giống việc người ta sơn vẽ chân dung một
99 con người, tẩy xóa chúng từ lịch sử như theo ý của Stalinesque. Ví dụ,
100 giả sử chúng ta có ý định phát hành dự án, nhưng lại liên đới đến một tệp tin mà nó phải được giữ bí mật
101 vì lý do nào đó. Chẳng hạn như tôi đã quên khi ghi lại số thẻ tín dụng vào trong một tệp tin
102 văn bản và ngẫu nhiên nó được thêm vào trong dự án. Việc xóa tệp tin này là
103 chưa đủ, bởi vì ta có thể đọc nó từ lần commit cũ. Chúng ta phải gỡ bỏ
104 tệp tin này từ tất cả các lần đã commit:
106  $ git filter-branch --tree-filter 'rm top/secret/file' HEAD
108 Xem *git help filter-branch*, nội dung của nó sẽ thảo luận về ví dụ này và đưa ra một cách thức
109 nhanh hơn. Đại thể, lệnh *filter-branch* giúp bạn thay đổi cả một chương lớn của lịch sử chỉ
110 chỉ bằng một lệnh đơn.
112 Sau này, thư mục +.git/refs/original+ mô tả trạng thái của công việc trước khi thực hiện. Kiểm tra lệnh filter-branch đã làm những thứ bạn muốn chưa, sau đó xóa thư mục này đi nếu bạn muốn chạy lệnh filter-branch lần nữa.
114 Cuối cùng, thay thế bản sao của dự án của bạn bằng phiên bản bạn đã sửa lại nếu bạn muốn tương thích với chúng sau này.
116 === Tự Tạo Lịch Sử ===
118 [[makinghistory]]
119 Bạn muốn chuyển đổi dự án của mình sang sử dụng Git? Nếu nó được quản lý bởi một hệ thống nổi tiếng hơn, thế thì nếu may mắn sẽ có người nào đó đã viết sẵn một đoạn kịch bản để xuất toàn bộ lịch sử ra thành Git.
121 Nếu không, thì nên xem xét đến việc sử dụng lệnh *git fast-import*, lệnh này đọc văn bản đầu vào ở một định dạng
122 riêng để mà tạo ra một lịch sử cho Git từ ban đầu. Thông thường một script sử dụng
123 lệnh này là một nhóm lệnh tổ hợp với nhau và chỉ chạy một lần, di chuyển một dự án chỉ bằng
124 một lệnh đơn.
126 Dưới đây là một ví dụ, dán danh sách theo sau đâu vào một tệp tin tạm thời nào đó, chẳng hạn như là `/tmp/history`:
127 ----------------------------------
128 commit refs/heads/master
129 committer Alice <alice@example.com> Thu, 01 Jan 1970 00:00:00 +0000
130 data <<EOT
131 Initial commit.
134 M 100644 inline hello.c
135 data <<EOT
136 #include <stdio.h>
138 int main() {
139   printf("Hello, world!\n");
140   return 0;
145 commit refs/heads/master
146 committer Bob <bob@example.com> Tue, 14 Mar 2000 01:59:26 -0800
147 data <<EOT
148 Replace printf() with write().
151 M 100644 inline hello.c
152 data <<EOT
153 #include <unistd.h>
155 int main() {
156   write(1, "Hello, world!\n", 14);
157   return 0;
161 ----------------------------------
163 Thế thì tạo một kho Git từ thư mục chứa các tệp tin tạm thời này bằng cách gõ:
165  $ mkdir project; cd project; git init
166  $ git fast-import --date-format=rfc2822 < /tmp/history
168 Bạn có thể checkout phiên bản cuối của dự án với:
170  $ git checkout master .
172 Lệnh *git fast-export* chuyển đổi bất kỳ một kho chứa nào thành định dạng
173 phù hợp với lệnh *git fast-import*, và bạn có thể nghiên cứu nó để tạo riêng cho mình một chương trình xuất,
174 và cũng làm như thế để tạo thành kho chuyên chở ở định dạng con người có thể đọc được. Thực vậy,
175 những lệnh này có thể gửi một kho chứa ở dạng văn bản thông qua một kênh chỉ cho phép văn bản truyền đi.
177 === Vị Trí Nào Phát Sinh Lỗi? ===
179 Bạn vừa mới phát hiện ra một đặc tính không hoạt động trong chương trình mà bạn chắc chắn là nó đã hoạt động vài tháng trước. Tệ quá! Bạn tự hỏi là lỗi bắt đầu từ chỗ nào nhỉ? Nếu như chỉ có mình bạn kiểm tra cũng như phát triển đặc tính này.
181 Lúc này thì đã quá muộn rồi. Tuy nhiên, chỉ cần bạn commit thường xuyên, Git
182 có thể xác định vị trí của trục trặc:
184  $ git bisect start
185  $ git bisect bad HEAD
186  $ git bisect good 1b6d
188 Git checks out một trạng thái nằm giữa chúng. Kiểm tra đặc tính kỹ thuật, và nếu nó vẫn hỏng:
190  $ git bisect bad
192 Nếu không thì thay "bad" bằng "good". Git sẽ chuyên chở bạn qua lại nửa bước giữa hai trạng
193 thái là phiên bản "tốt" và "xấu", thu hẹp khả năng lại. Sau khi lặp đi lặp lại một số lần,
194 việc tìm kiếm nhị phân này sẽ dẫn bạn đến lần commit mà nó làm nguyên nhân dẫn đễ hỏng hóc.
195 Một khi bạn đã hoàn tất việc điều tra, trở lại trạng thái nguyên bản
196 của bạn bằng cách gõ:
198  $ git bisect reset
200 Thay vì thử nghiệm mọi thay đổi một cách thủ công, hãy tự động hóa sự tìm kiếm này bằng cách chạy:
202  $ git bisect run my_script
204 Git sử dụng giá trị trả về của lệnh đã cho, thông thường là từ các đoạn kịch bản, để
205 quyết định là lệnh đã thực hiện tốt hay không: lệnh sẽ trả về giá trị 0
206 khi tốt, 125 khi sự thay đổi bị bỏ qua, và bất kỳ giá trị nào khác nằm giữa 1
207 và 127 nếu gặp lỗi. Một giá trị âm sẽ bãi bỏ lệnh bisect.
209 Bạn có thể làm nhiều hơn thế: trang trợ giúp giảng giải cho bạn làm thế nào để hiểu
210 được lệnh bisect làm việc như thế nào, xem xét hay xem lại nhật ký lệnh bisect,
211 và loại trừ các thay đổi ngớ ngẩn để tăng tốc độ tìm kiếm.
213 === Ai Đã Làm Nó Sai? ===
215 Giống như các hệ thống quản lý mã nguồn khác, Git cũng có lệnh blame:
217  $ git blame bug.c
219 lệnh này chú thích tất cả các dòng có trong tệp tin được chỉ ra cho thấy ai là người cuối cùng sửa nó, và là khi nào. Không giống các hệ thống quản lý mã nguồn khác, hành động này hoạt động không cần có mạng, việc đọc chỉ đơn thuần từ ổ đĩa của máy tính cá nhân.
221 === Kinh Nghiệm Riêng ===
223 Trong một hệ thống quản lý mã nguồn tập trung, thay đổi lịch sử là một việc làm
224 khó khăn, và chỉ làm được thế nếu đó là người quản trị. Việc nhân bản, tạo nhánh và
225 trộn không thể thiếu việc truyền thông qua mạng. Cũng như thế với các tác vụ cơ bản khác
226 như là duyệt lịch sử, hay là commit một thay đổi. Trong một số hệ thống khác, người dùng
227 yêu cầu có kết nối mạng chỉ để xem các thay đổi của họ hay mở một tệp tin
228 để biên tập.
230 Hệ thống tập trung không cho phép làm việc mà không có mạng, và đòi hỏi cơ sở hạ tầng mạng máy tính
231 đắt đỏ tốn kém, đặc biệt là khi số nhà phát triển phần mềm tăng lên. Điều quan trọng,
232 tất cả mọi tác vụ sẽ chậm hơn ở mức độ nào đó, thường thường
233 những người sử dụng sẽ lảng tránh việc sử dụng các lệnh cao cấp trừ phi nó thực sự cần thiết. Trừ những trường hợp
234 đặc biệt là các lệnh cơ bản. Khi những người dùng phải chạy
235 các lệnh chạy chậm, hiệu suất bị giảm bởi vì nó làm gián đoạn công việc của cả một dây truyền.
237 Tôi trực tiếp đã trải qua những hiện tượng đó. Git là hệ thống quản lý mã nguồn đầu tiên tôi sử dụng. 
238 Tôi nhanh chóng làm quen với nó, bị quyến rũ bởi những đặc tính kỹ thuật mà nó đã cung cấp.
239 Tôi đơn giản cho rằng các hệ thống khác thì cũng tương tự: việc chọn lựa một
240 hệ thống quản lý mã nguồn thì cũng chẳng khác việc chọn một trình biên soạn hay một
241 trình duyệt web.
243 Tôi sẽ sốc nếu như sau này bị bắt buộc sử dụng hệ thống quản lý mã nguồn tập trung. Một kết nối
244 Internet chậm chạp cũng chẳng phải là vấn đề lớn đối với Git, nhưng nó sẽ làm cho các
245 nhà phát triển phần mềm không thể chịu nổi khi nó cần sự tin cậy như ổ đĩa nội bộ. Thêm nữa,
246 tôi đã gặp một số mắc mớ với một số lệnh, mà chính nó
247 đã ngăn cản tôi làm việc một cách trôi chảy.
249 Khi tôi phải chạy những lệnh cần nhiều thời gian, việc làm ngắt quãng việc suy nghĩ
250 sẽ gây nên thiệt hại rất to lớn. Trong khi chờ cho việc truyền thông
251 với máy chủ hoàn tất, tôi sẽ phải làm một vài thứ gì đó khác để lấp chỗ trống, chẳng hạn như
252 lấy thư điện tử hay viết tài liệu. Sau một khoảng thời gian tôi quay trở lại nhiệm vụ
253 chính của mình, lệnh đã hoàn tất từ lâu rồi, và tôi phải lãng phí thêm nhiều thời gian nữa
254 để nhớ lại xem mình đang làm gì. Con người thường dở khi phải thay đổi mạch văn.
256 Ở đây còn có một hậu quả rất đáng quan tâm nữa: đoán trước được việc tắc nghẽn của mạng máy tính,
257 nhiều cá nhân riêng lẻ có thể chiếm dụng nhiều lưu lượng mạng hơn cần thiết trên các tác vụ
258 khác nhau để cố gắng giảm thiểu sự chậm trễ có thể xảy ra trong tương lai. Hậu quả cuối cùng là
259 sự quá tải quá mức, chính việc vô tình ủng hộ việc tiêu dùng cá nhân như thế đã tiêu tốn nhiều lưu lượng mạng hơn
260 và sau đó nó làm cho việc tắc nghẽn càng lúc càng trở nên tồi tệ hơn.