30 tháng 11, 2017

Tìm kiếm với Git

Git là một công cụ quản lý phiên bản tuyệt vời, bạn sẽ không bao giờ "để lỡ" bất cứ điều gì với công cụ này. Tuy nhiên, đôi khi sẽ rất khó khăn trong việc tìm kiếm lại thông tin của những thứ bạn cần. Hầu hết, chúng ta sẽ sử dụng git log, nhưng sẽ không phải là cho tất cả mọi thứ.

1. Tìm kiếm file

Thỉnh thoảng, chúng ta biết chắc chắn là có một file cụ thể nào đó trong repository, nhưng lại không thể biết được chính xác vị trí của file đó nằm ở đâu. git ls-files là thứ mà chúng ta sẽ cần.

$ git ls-files | grep security
lib/dynamo-db/security.js
test/security-test.js

Bạn có thể sử dụng bất kì tùy chọn cụ thể nào mà bạn thích của lệnh grep, ví dụ như -i để không biệt chữ hoa, chữ thường.

2. Tìm những file có từ phù hợp

Nếu bạn muốn tìm thông tin bên trong file thì bạn có thể sử dụng lệnh git grep. Lệnh git grep hoạt động tương tự lệnh grep đệ quy grep -r . trong linux, nhưng nó chỉ tìm kiếm những file được quản lí bởi git.

# Tìm tất cả những dòng phù hợp với pattern *crypt* trong version hiện tại
$ git grep 'crypt'
lib/dynamo-db/security.js:var crypto = require('crypto');
lib/dynamo-db/security.js: var hmac = crypto.createHmac('sha256', key);

# Thêm thông tin số dòng vào kết quả tìm được
$ git grep -n 'crypt'
lib/dynamo-db/security.js:2:var crypto = require('crypto');
lib/dynamo-db/security.js:15: var hmac = crypto.createHmac('sha256', key);

# Chỉ liệt kê tên file
$ git grep -l 'crypt'
lib/dynamo-db/security.js

# Liệt kê số lượng pattern xuất hiện trong file
$ git grep -c 'crypt'
lib/dynamo-db/security.js:2

Cũng có thể chỉ ra phiên bản để grep nhằm tìm ra những thay đổi giữa các phiên bản

# Tìm tất cả các file kèm với số dòng mà phù hợp với điều kiện tìm kiếm *type* trong các phiên bản `master` và `8f0fb7f`
$ git grep -l type master 8f0fb7f
master:lib/dynamo-db/index.js
master:lib/dynamo-db/security.js
master:package.json
8f0fb7f:lib/dynamo-db/index.js
8f0fb7f:package.json

Git có thể kết hợp với hầu hết các lệnh cơ bản của Linux như grep, find, ack,... Nhưng Git là một công cụ quản lí phiên bản, vì vậy làm cách nào để ta có thể tìm kiếm những việc đã xảy ra trong quá khứ?

3. Tìm kiếm người đã xóa file

Giả sử, bạn đang làm việc trong một số dự án, và "gấu" của bạn bất ngờ bị ốm, bạn phải ở nhà làm việc để tiện chăm sóc cho "gấu", khi công việc quay trở lại bình thường thì bạn nhận thấy đã có ai đó xóa file của bạn khỏi dự án. Bạn muốn biết ai đã làm việc đó. git log sẽ giúp bạn giải quyết được vấn đề này.

git log sẽ cho bạn thấy nội dung log của các commit. Đây là đôi mắt của bạn để nhìn được về quá khứ.

# File của tôi bị xóa khi nào?
$ git log --diff-filter=D -- test/create-table-test.js
commit ba6c4d8bc165b8fb8208979c3e5513bd53477d51
Author: Nguyen Van A <nguyen.van.a@example.com>
Date: Thu Nov 30 09:46:52 2017 +0700

Removed the stupid failing test.

Có vẻ như chính bạn đã xóa file đó đi khi đang làm việc tại nhà và phải chăm sóc "gấu" đang bị ốm. Nhưng liệu thực sự file đó bị xóa trong commit này. Để xem thêm thông tin, hãy thêm tùy chọn --summary

# Tìm thời gian và commit mà file bị xóa
$ git log --diff-filter=D --summary -- test/create-table-test.js
commit ba6c4d8bc165b8fb8208979c3e5513bd53477d51
Author: Nguyen Van A <nguyen.van.a@example.com>
Date: Thu Nov 30 09:46:52 2017 +0700

Removed the stupid failing test.

delete mode 100644 test/create-table-test.js

Có vẻ như file đó đúng là do chính bạn đã xóa đi.

Chúng ta cùng phân tích câu lệnh trên:

  • test/create-table-test.js - Đường dẫn tương đối đến file của bạn.
  • -- - Sử dụng hai đấu gạch nối để báo cho Git biết đây không phải là một branch hoặc là một tùy chọn của một lệnh.
  • --summary - Cho bạn biết những file nào đã bị xóa hoặc thêm mới. Ta cũng có tùy chọn khác có chức năng tương tự --name-status.
  • --diff-filter - Giới hạn log bằng việc chỉ định loại thay đổi, trong trường hợp này là D nghĩa là Deleted. Các tùy chọn khác gồm có: Added (A), Coppied (C), Modified (M) và Renamed (R).

4. Tìm thời gian mà file được thêm vào

Cách thực hiện tương tự với kĩ thuật bên trên, nhưng tôi sẽ thay đổi nó vì không muốn gõ đường dẫn đầy đủ của file

# Tìm thời gian mà các file integration test được thêm vào.
$ git log --diff-filter=A --name-status | grep -C 6 'integ'
commit 09420cfea8c7b569cd47f690104750fec358a10a
Author: Nguyen Van A <nguyen.van.a@example.com>
Date: Thu Nov 30 09:46:52 2017 +0700

Extracted integration test

A	integration-test/sts-test.js

commit 205db3965dec6c2c4c7b2bb75387a591d49e1951
Author: Nguyen Van A <nguyen.van.a@example.com>
Date: Thu Nov 30 09:46:52 2017 +0700

Như các bạn có thể thấy, ở đây tôi đang sử dụng tùy chọn --name-status làm biến thể của --summary.

Tôi sử dụng lệnh grep -C 6 để lấy ra bối cảnh xung quanh các yếu tố được tìm thấy, trong trường hợp này sẽ là sáu dòng trước và sau dòng có nội dung thỏa mãn với điều kiện tìm kiếm.

5. Tìm người cuối cùng sửa code

Để xem thông tin người cuối cùng tác động đến một dòng code của một file, bạn có thể dùng đến lệnh git blame.

$ git blame test/security-test.js
205db396 (Nguyen Van B 2017-11-21 10:03:59 +0700  1) var vows = require('vows'),
205db396 (Nguyen Van B 2017-11-21 10:03:59 +0700  2)     assert = require('assert');
205db396 (Nguyen Van B 2017-11-21 10:03:59 +0700  3) 
09420cfe (Nguyen Van B 2017-11-24 16:23:52 +0700  4) var access = 'access';
09420cfe (Nguyen Van B 2017-11-24 16:23:52 +0700  5) var secret = 'secret';
90b65208 (Nguyen Van B 2017-11-21 11:58:21 +0700  6) 
205db396 (Nguyen Van B 2017-11-21 10:03:59 +0700  7) var security = new Security({
90b65208 (Nguyen Van B 2017-11-21 11:58:21 +0700  8)   access: access,
90b65208 (Nguyen Van B 2017-11-21 11:58:21 +0700  9)   secret: secret
205db396 (Nguyen Van B 2017-11-21 10:03:59 +0700 10) });
...

Như bạn thấy, mỗi dòng đều được đánh dấu bởi commit mới nhất đã tác động đến nó và tác giả của commit đó.

6. Tìm commit có chứa chuỗi kí tự chỉ định

Ta có thể tìm được những commit đã xóa bỏ hoặc thêm mới một chuỗi kí tự bằng cách sử dụng lệnh git log -S<string> hoặc git log -G<regex>.

# Tìm những commit có thay đổi chuỗi 'aws' và hiển thị tất cả thay đổi trong những commit đó.
$ git log -Saws --diff-filter=M --patch
commit b96c68b839f204b310b79570bc3d27dc93cff588
Author: Anders Janmyr <anders@janmyr.com>
Date:   Sat Jan 21 12:33:50 2012 +0100

    We have a valid request, tjohoo

diff --git a/lib/dynamo-db/security.js b/lib/dynamo-db/security.js
index bee6936..8471527 100644
--- a/lib/dynamo-db/security.js
+++ b/lib/dynamo-db/security.js
@@ -2,6 +2,7 @@
 var crypto = require('crypto');
 var _ = require('underscore');
 var request = require("request");
+var xml2js = require('xml2js');
 
 function Security(options) {
   this.options = options;
@@ -23,7 +24,7 @@ mod.timestamp = function() {
 mod.defaultParams = function() {
   return {
     AWSAccessKeyId: this.options.access,
-    Version: '2010-05-08',
+    Version: '2011-06-15',
     Timestamp: this.timestamp(),
     SignatureVersion: 2,
     SignatureMethod: 'HmacSHA256'
@@ -57,9 +58,10 @@ mod.url = function(host, path, params) {
 
 mod.makeRequest = function(method, host, path, params, callback) {
   var extParams = _.extend({}, this.defaultParams(), params);
-  var signedParams = this.signedParams('GET', 'iam.amazonaws.com', '/', extParams);
-  console.log(extParams,signedParams);
-  return request({ method: method, url: this.url(host, path, signedParams) },
+  var signedParams = this.signedParams(method, host, path, extParams);
+  var url = this.url(host, path, signedParams);
+  console.log(url,signedParams);
+  return request({ method: method, url: url },
...

2 nhận xét: