Là một rails developer thì chắc chằn bạn không hề lạ lẫm với Rubocop. Rubocop là một công cụ để kiểm tra code style dựa trên ruby-style-guide, xây dựng lên để phục vụ cho developers. Việc sử dụng Rubocop trong dự án sẽ giúp bạn tiết kiệm rất nhiều thời gian cho việc review coding convention, đảm bảo code không bị mắc phải những lỗi cơ bản. Nhưng đôi khi bạn phải đổi mặt với việc phải chạy rubocop trên mọi file dù file đó không được thay đổi gì. Điều đó thật sự phiền toái và tốn thời gian. Hoặc khi bạn muốn áp dụng rubocop vào 1 source có sẵn và bạn không đủ effort để sửa tất cả các lỗi rubocop trên những file cũ. Lúc này việc chạy rubocop trên những file được thay đổi trở nên khá cần thiết.

Kết hợp với git ta có 2 các để chạy Rubocop chỉ với các file thay đổi.

Trước khi commit

Giả sử bạn có 1 branch với trạng thái như sau:

~/workspace/rubocop_modified$ git status
On branch before_commit
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/assets/javascripts/application.js
	deleted:    app/assets/javascripts/high_scores.coffee
	modified:   app/controllers/high_scores_controller.rb
	deleted:    app/helpers/high_scores_helper.rb

no changes added to commit (use "git add" and/or "git commit -a")

Để lấy danh sách file thay đổi, bạn có thể làm như sau:

	$ git ls-files -m
	
	Result:
	app/assets/javascripts/application.js
	app/assets/javascripts/high_scores.coffee
	app/controllers/high_scores_controller.rb
	app/helpers/high_scores_helper.rb

Các bạn có thể xem thêm tại document của git: https://git-scm.com/docs/git-ls-files. Danh sách này liệt kê tất cả các tệp được sửa đổi(không quan tâm đến phần mở rộng) cũng như các tệp đã xóa. Để loại trừ các tệp đã bị xóa bạn có thể thực hiện như sau:

	$ git ls-files -m | xargs ls -1 2>/dev/null
	
	Result:
	app/assets/javascripts/application.js
	app/controllers/high_scores_controller.rb

Bây giờ bạn chỉ muốn lấy danh sách những file có extension là .rb, bạn có thể làm như sau:

	$ git ls-files -m | xargs ls -1 2>/dev/null | grep '\.rb$'
	
	Result:
	app/controllers/high_scores_controller.rb

Cuối cùng bạn chỉ cần chạy rubucop với danh sách file nhận được:

	git ls-files -m | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs rubocop

Sau khi commit

Bây giờ trạng thái branch của bạn như sau:

~/workspace/rubocop_modified$ git status
On branch after_commit
nothing to commit, working directory clean
~/workspace/rubocop_modified$ git diff develop
....Code diff display in here....

Ý tưởng cũng tương tự như trên, lấy ra danh sách file. Về cách thực hiện có hơi khác một chút:

	git diff-tree -r --no-commit-id --name-only <current_branch_name> <target_branch>
	
	Áp dung:
	git diff-tree -r --no-commit-id --name-only HEAD develop
	
	Result:
	app/assets/javascripts/application.js
	app/assets/javascripts/high_scores.coffee
	app/controllers/high_scores_controller.rb
	app/helpers/high_scores_helper.rb

Các bạn có thể xem thêm các option khác của git diff-tree tại đây: https://git-scm.com/docs/git-diff-tree

Kết hợp với ở trên ta có lệnh như sau:

	git diff-tree -r --no-commit-id --name-only HEAD develop | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs rubocop

Tài liệu tham khảo