Re-organize lại pull request với git
Git
54
White

huydx viết ngày 10/05/2016

Bài toán: Mình pull request một cái issue to bự trên github. Ngay từ đầu mình nghĩ là không cần thiết nên đã không break nhỏ issue thành nhiều commits có ý nghĩa.

alt text

Vấn đề của cách làm trên là với tư cách của người review thì phải nhìn một cái PR to tổ chảng thì sẽ rất khó để họ review.
Và với tư cách của người review thì sếp mình đã thẳng thừng reject và bảo rằng:

Hãy chia nhỏ big PR kia thành nhiều commits có ý nghĩa đi

Việc đầu tiên mình nghĩ đến là, hãy reset lại commit trước khi có cái PR này đã, rồi tính tiếp. Việc này thì đơn giản vô cùng rồi

git reset hashid

Sau đó kết quả là một loạt các file unstaged (chưa được add lên stage của local git)

Unstaged changes after reset:
M   app/controllers/GraphController.java
M   app/jp/naver/bot/health/DataSource.java
M   app/jp/naver/bot/health/GraphDAO.java
M   app/jp/naver/bot/health/GroupMonitoringChecker.java
M   app/jp/naver/bot/health/GroupMonitoringDAO.java
M   app/views/ignore.scala.html
M   app/views/index.scala.html
M   conf/routes
D   public/javascripts/hello.js
D   public/stylesheets/main.css
D   public/stylesheets/others/css/styles.css
M   sql/insert_160427.sh
M   test/jp/naver/bot/health/GroupMonitoringTest.java

Việc tiếp theo là organize lại đống file loằng ngoằng trên thành các commits có ý nghĩa. Bạn nghĩ thầm "có vẻ đơn giản, chỉ cần add từng file có ý nghĩa chung lại, sau đó mỗi lần gộp đó commit một cái". Nếu những thay đổi của bạn phân biệt được theo file thì quả nhiên là đơn giản, tuy nhiên phải làm sao khi mà một file của bạn có chứa nhiều thay đổi mà bạn muốn chia thành nhiều commit khác nhau. Hay tóm gọn hơn là bạn muốn chia thay đổi của 1 file thành nhiều commit.

Nếu làm một cách thủ công, bạn sẽ phải làm

  1. Copy file ra 1 file backup
  2. modify file hiện tại bằng cách xoá đi những chỗ thay đôi không ý nghĩa
  3. Copy back
  4. Commit
  5. Repeat from 1

Tại sao lại phải thủ công thế????? (bạn thầm nghĩ). Vậy có cách nào mà không phải thủ công không nhỉ?

Git đã cung cấp cho chúng ta một công cụ gọi là patch add dùng để add một file lên stage "từng phần". Để sử dụng tính năng này thì rất đơn giản, bạn chỉ cần gõ

git add -p filename

Khi đó sẽ hiện ra một cái giao diện na ná như sau:

➜  *** git:(*******) ✗ git add -p app/controllers/GraphController.java
diff --git a/app/controllers/GraphController.java b/app/controllers/GraphController.java
index 55f6c18..46af711 100644
--- a/app/controllers/GraphController.java
+++ b/app/controllers/GraphController.java
@@ -51,7 +51,14 @@ public class GraphController extends Controller {
     public Result index() throws SQLException, IOException {
         String predefine = Files.toString(new File(defaultLogicJsFile), Charset.forName("UTF-8"));
         List<GraphInfo> graphs = graphDao.getGraphs(true);
-        return ok(views.html.index.render(graphs, predefine));
+
+        //manual watched graph is priority in display
+        graphs.sort((l,r) -> {
+            if (l.isAutoWatched()) return 1;
+            else return -1;
+        });
+        List<GroupMonitoringInfo> groupMonitoringInfos = Lists.newArrayList(groupMonitoringDAO.getAllGroupMonitoring());
+        return ok(views.html.index.render(graphs, groupMonitoringInfos, predefine));
     }

     public Result upsertGraph() throws Exception {
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]?

Bạn chỉ cần chú ý đến dòng Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? thôi :smile:
Có một concept mới xuất hiện trong dòng này, đó là hunk. Bạn có thể hiểu hunk là một thay đổi trong code, với phạm vi nhỏ hơn file.
Vậy có thể hiểu đoạn ở trên nghĩa là: git nhận diện được một thay đổi nhỏ trong file GraphController.java, với nội dung như vậy, và bạn muốn làm gì tiếp theo.
Git cung cấp cho chúng ta một số lựa chọn để thao tác vơi hunk nhận diện được

Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ?
y - stage this hunk
n - do not stage this hunk
a - stage this and all the remaining hunks in the file
d - do not stage this hunk nor any of the remaining hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

Mình thường sử dụng 3 option là y, ns.
y có nghĩa là đồng ý, n là không đồng ý, và s là: hãy chia nhỏ hunk này hơn nữa xem sao.

Nếu mình ấn y, và sau đó kiểm tra lại bằng git status thì

On branch ******
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   app/controllers/GraphController.java

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   app/controllers/GraphController.java

Bạn có thể thấy file GraphController vừa thuộc phần changes to be commited vừa thuộc phần not staged to commit, và nếu sử dụng git diff để xem thay đổi thì bạn có thể thấy phần code thuộc hunk ở trên vừa được add vào changes to be commited.

Tiếp đến bạn commit phần thay đổi này và tiếp tục với các file tiếp theo, và bạn đã có thể chia nhỏ 1 commits to thành nhiều commit nhỏ rồi..
Bạn có thể tham khảo thêm ở https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging

Happy git-ting.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

huydx

116 bài viết.
940 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
148 14
Introduction (Link) là một cuộc thi ở Nhật, và cũng chỉ có riêng ở Nhật. Đây là một cuộc thi khá đặc trưng bởi sự thú vị của cách thi của nó, những...
huydx viết gần 2 năm trước
148 14
White
118 15
Happy programmer là gì nhỉ, chắc ai đọc xong title của bài post này cũng không hiểu ý mình định nói đến là gì :D. Đầu tiên với cá nhân mình thì hap...
huydx viết hơn 3 năm trước
118 15
White
95 10
(Ảnh) Mở đầu Chắc nhiều bạn đã nghe đến khái niệm oauth. Về cơ bản thì oauth là một phương thức chứng thực, mà nhờ đó một web service hay một ap...
huydx viết gần 3 năm trước
95 10
Bài viết liên quan
White
49 8
Tôi xin tổng hợp các cách dùng git stash tôi hay sử dụng Lưu lại thay đổi Git stash được sử dụng khi muốn lưu lại các thay đổi chưa commit, thườ...
BB viết 3 năm trước
49 8
White
13 2
Xin chào các bạn. Chắc hẳn mỗi chúng ta đều đã từng phát triển app sử dụng API của bên thứ 3, và chắc mọi người đều biết là hầu hết các API service...
Hải Nguyễn viết hơn 1 năm trước
13 2
White
5 7
Thông thường một feature mới thường được làm trên một nhánh (branch) riêng và thường xuyên pull các cập nhật từ nhánh master trong quá trình đấy. S...
Lơi Rệ viết gần 3 năm trước
5 7
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
116 bài viết.
940 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!