Tham Khảo Git

 

book Cơ Bản Về Bản Sao

Làm việc với Git chủ yếu bao gồm tạo và so sánh các bản sao của dự án. Phần này trình bày về những lệnh cần thiết để tạo và xác nhận các bản sao.

Một khái niệm quan trọng của Git là 'chỉ mục'. Có thể được coi nó là một vùng tạm thời trước khi tạo bản sao chính, nhờ nó bạn có thể tạo những bản sao bao gồm một nhóm các chỉnh sửa được tổ chức tốt, thay vì phải xác nhận chỉnh sửa của tất cả các tập tin cùng một lúc.

Tóm tắt:, quá trình làm việc cơ bản với Git của bạn sẽ như sau: sử dụng lệnh git add để bắt đầu theo dõi tập tin mới và cũng để chỉ mục các tập tin cũ đã chỉnh sửa. Sau đó dùng lệnh git statusgit diff để xem lại các chỉnh sửa đã được chỉ mục, và cuối cùng dùng lệnh git commit để lưu lại bản sao của dự án.

docs   book git add thêm nội dung tập tin vào vùng chỉ mục

Với git, bạn phải thêm tập tin vào vùng chỉ mục trước khi bạn có thể xác nhận. Bạn có thể dùng lệnh git add để thêm cả tập tin mới cũng như những tập tin đã được theo dõi (ví dụ như tập tin từ những lần xác nhận trước) vào vùng chỉ mục. Dưới đây là một vài ví dụ.

Ở ví dụ Hello World, sau khi khởi tạo dự án, ta sẽ bắt đầu thêm tập tin vào bằng cách dùng git add. Chúng ta có thể dùng git status để xem trạng thái hiện tại của dự án.

$ git status -s
?? README
?? hello.rb
Hiện tại có hai tập tin chưa được theo dõi. Chúng ta có thể thêm chúng vào dự án.
$ git add README hello.rb
Bây giờ nếu chạy git status một lần nữa, chúng ta sẽ thấy chúng đã được thêm.
$ git status -s
A  README
A  hello.rb

Git có thể thêm một cách đệ qui tất cả các tập tin trong một thư mục, do đó để thêm tất cả các tập tin trong thư mục dự án, ta cũng thường dùng git add .. Việc dùng git add . cũng có tác dụng như khi bạn gõ lệnh git add README hello.rb, và nếu như trong thư mục hiện tại không có thêm thư mục con nào thì tác dụng của lệnh git add .git add * có thể nói là như nhau.

Nếu bây giờ chúng ta sửa một tập tin và tiếp tục thực hiện lệnh git status, kết quả sẽ như thế này.

$ vim README
$ git status -s
AM README
A  hello.rb

Trạng thái 'AM' có nghĩa là tập tin đã được chỉnh sửa sau khi ta thêm tập tin đó vào (chữ 'A' chỉ 'Add', hay thêm vào, còn chữ 'M' chỉ 'Modified', hay chỉnh sửa). Nếu bây giờ ta xác nhận, Git sẽ xác nhận tập tin này vào thời điểm ta gõ lệnh git add trước, không phải phiên bản ta vừa lưu sửa đổi trên đĩa. Đó là vì Git không mặc định lưu mọi tập tin có trong thư mục đang làm việc vào bản sao, mà bạn phải chỉ định cụ thể Git thêm tập tin nào vào thông qua lệnh git add.

Tóm tắt:, dùng git add để thêm tập tin đã chỉnh sửa vào phiên bản trước khi tiến hành xác nhận. Chỉ những chỉnh sửa nào được thêm vào mới được xác nhận vào kho, nhờ vậy mà các phiên bản có thể bao gồm chính xác những tập tin bạn muốn.

Có một ví dụ rất thú vị về cách áp dụng tính mềm dẻo này để chỉ mục chỉ một phần của tập tin đã chỉnh sửa ở phần tùy chọn -p của git add trong sách Pro Git.

docs   book git status xem trạng thái tập tin trong thư mục làm việc và vùng tạm

Như đã thấy trong mục git add, để xem trạng thái vùng chỉ mục so với thư mục đang làm việc, ta dùng lệnh git status. Để xem kết quả ngắn gọn, ta thêm tùy chọn -s. Nếu không có tùy chọn nào, lệnh git status sẽ cho thấy nhiều thông tin chi tiết và gợi ý. Dưới đây là kết quả của cùng một trạng thái khi có và không có -s. Đầu tiên là kết quả ngắn gọn:

$ git status -s
AM README
A  hello.rb
Khi không dùng tham số -s, kết quả xuất ra chi tiết hơn:
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
# new file:   README
# new file:   hello.rb
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified:   README
#

Rất dễ để nhận ra sự khác biệt giữa hai kết quả trên. Dạng đầy đủ có chứa gợi ý về lệnh mà ta sẽ dùng tiếp theo.

Git cũng sẽ cho thấy những tập tin đã bị xóa và tập tin bị chỉnh sửa hay đã được chỉ mục kể từ lần xác nhận trước.

$ git status -s
M  README
 D hello.rb

Dạng ngắn của trạng thái bao gồm hai cột. Cột đầu tiên dành mô tả trạng thái các tập tin trong chỉ mục tạm, còn cột thứ hai là dành liệt kê các tập tin ở thư mục hiện hành. Nếu bạn đã sửa tập tin README sau khi chỉ mục nó vào vùng tạm mà không thực hiện lệnh git add lần nữa, kết quả sẽ như thế này:

$ git status -s
MM README
 D hello.rb

Tóm tắt: dùng lệnh git status khi cần xem những chỉnh sửa và/hoặc đã đưa vào vùng chỉ mục để quyết định xem có nên xác nhận lưu lại chúng hay không.

docs   book git diff hiển thị những chỉnh sửa của tập tin đã chỉ mục và chưa đưa vào chỉ mục

Lệnh git diff có hai công dụng chính. Chúng ta sẽ nói đến công dụng thể hiện những chỉnh sửa đã được chỉ mục hoặc chưa được chỉ mục. Công dụng còn lại sẽ được đề cập đến trong trong phần "Kiểm tra và so sánh".

git diff chỉ ra những chỉnh sửa chưa được chỉ mục

Mặc định git diff sẽ hiển thị tổng hợp những sự chỉnh sửa (một bản vá) mà bạn vừa tạo ra so với lần xác nhận trước mà chưa được ghi nhận cho lần xác nhận kế tiếp.

$ vim hello.rb
$ git status -s
 M hello.rb
$ git diff
diff --git a/hello.rb b/hello.rb
index d62ac43..8d15d50 100644
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,7 @@
 class HelloWorld

   def self.hello
-    puts "hello world"
+    puts "hola mundo"
   end

 end

Trong khi lệnh git status sẽ cho ta biết tập tin nào đã bị chỉnh sửa hay đã được chỉ mục kể từ lần xác nhận trước, lệnh git diff sẽ chỉ ra những chỉnh sửa đó chính xác là như thế nào theo từng dòng. Lệnh này nên được dùng ngay sau git status

git diff --cached hiển thị những chỉnh sửa đã được chỉ mục

Lệnh git diff --cached sẽ cho ta thấy những chỉnh sửa nào đã được chỉ mục, có nghĩa là những chỉ mục sẽ được đưa vào bản sao tiếp theo khi xác nhận. Ở ví dụ trên, nếu bạn đã chỉ mục các chỉnh sửa tập tin hello.rb, khi dùng lệnh git diff sẽ không xuất ra thông tin gì cho bạn vì lệnh này chỉ xuất thông tin những gì chưa được chỉ mục.

$ git status -s
 M hello.rb
$ git add hello.rb 
$ git status -s
M  hello.rb
$ git diff
$ 

Để xem những chỉnh sửa đã được chỉ mục, bạn dùng lệnh git diff --cached

$ git status -s
M  hello.rb
$ git diff
$ 
$ git diff --cached
diff --git a/hello.rb b/hello.rb
index d62ac43..8d15d50 100644
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,7 @@
 class HelloWorld

   def self.hello
-    puts "hello world"
+    puts "hola mundo"
   end

 end

git diff HEAD xem tất cả các chỉnh sửa đã chỉ mục hoặc chưa chỉ mục

Để xem tất cả những chỉnh sửa đã chỉ mục và chưa chỉ mục cùng một lúc, bạn có thể dùng lệnh git diff HEAD. Về cơ bản nghĩa là bạn muốn xem những chỉnh sửa so với lần xác nhận trước. Nếu ta chỉnh sửa tập tin hello.rb, chỉ mục vài chỉnh sửa và không chỉ mục vài chỉnh sửa khác. Chúng ta hãy xem kết quả khi dùng ba lệnh diff này:

$ vim hello.rb 
$ git diff
diff --git a/hello.rb b/hello.rb
index 4f40006..2ae9ba4 100644
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,7 @@
 class HelloWorld

+  # says hello
   def self.hello
     puts "hola mundo"
   end

 end
$ git diff --cached
diff --git a/hello.rb b/hello.rb
index 2aabb6e..4f40006 100644
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,7 @@
 class HelloWorld

   def self.hello
-    puts "hello world"
+    puts "hola mundo"
   end

 end
$ git diff HEAD
diff --git a/hello.rb b/hello.rb
index 2aabb6e..2ae9ba4 100644
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,8 @@
 class HelloWorld

+  # says hello
   def self.hello
-    puts "hello world"
+    puts "hola mundo"
   end

 end

git diff --stat xem tóm tắt những chỉnh sửa

Lệnh git diff --stat cho kết quả chi tiết hơn so với lệnh git status, nhưng lại tóm lược hơn so với các lệnh diff trên. Đây là ví dụ với tùy chọn --stat.

$ git status -s
MM hello.rb
$ git diff --stat
 hello.rb |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
$ git diff --cached --stat
 hello.rb |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
$ git diff HEAD --stat
 hello.rb |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

Bạn cũng có thể thêm đường dẫn đến tập tin vào sau các tùy chọn này để giới hạn kết quả của lệnh diff cho một tập tin hay trong một thư mục con.

Tóm tắt: lệnh git diff dùng để xem chi tiết hơn lệnh git status - xem tập tin đã được chỉnh sửa hoặc ghi nhận như thế nào theo từng dòng.

docs   book git commit ghi lại một bản sao của vùng chỉ mục

Sau khi những chỉnh sửa đã được chỉ mục bằng lệnh git add, bạn dùng lệnh git commit để thực sự ghi những chỉnh sửa đó thành một bản sao. Git ghi lại tên và email của bạn trong mỗi xác nhận bạn tạo, vì vậy, bạn hãy thông tin về bạn cho Git biết.

$ git config --global user.name 'Your Name'
$ git config --global user.email you@somedomain.com

Bây giờ ta sẽ chỉ mục và xác nhận tất cả những chỉnh sửa của tập tin hello.rb. Trong ví dụ này, chúng ta sẽ dùng tùy chọn -m để nhập thông điệp xác nhận từ dòng lệnh.

$ git add hello.rb 
$ git status -s
M  hello.rb
$ git commit -m 'my hola mundo changes'
[master 68aa034] my hola mundo changes
 1 files changed, 2 insertions(+), 1 deletions(-)

Bản sao đã được ghi lại. Nếu bây giờ ta thực hiện lệnh git status, kết quả nhận được sẽ là ta có một "thư mục hiện hành trống", có nghĩa là chúng ta chưa thực hiện chỉnh sửa nào kể từ lần xác nhận gần nhất.

$ git status
# On branch master
nothing to commit (working directory clean)

Nếu không dùng tùy chọn -m, Git sẽ mở một trình soạn thảo văn bản để bạn viết thông điệp xác nhận. Theo mặc định trình soạn thảo văn bản là vim, và giao diện sẽ tương tự như thế này:


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# modified:   hello.rb
#
~
~
".git/COMMIT_EDITMSG" 9L, 257C

Lúc này bạn có thể thêm thông điệp xác nhận vào phần đầu văn bản. Những dòng bắt đầu bằng '#' sẽ bị bỏ qua - Git sẽ hiển thị kết quả của lệnh git status ở đây để bạn nhớ bạn đã sửa và chỉ mục những gì.

Thông thường, việc viết một thông điệp xác nhận tốt là rất quan trọng. Đối với các dự án nguồn mở, có một quy tắc chung về việc viết thông điệp xác nhận:

Tóm lược ngắn (50 ký tự hoặc ít hơn) về những chỉnh sửa

Thông tin chi tiết hơn nếu cần thiết. Giới hạn trong 72 ký tự trên một
dòng. Trong nhiều hoàn cảnh, dòng đầu tiên được coi như chủ đề và phần
còn lại là nội dung của một email. Dòng trống phân cách giữa tóm tắt và
phần thân rất quan trọng (trừ khi bỏ qua hoàn toàn phần thân); Một số
công cụ git có thể bị nhầm lẫn nếu bạn viết liền hai phần này với nhau.

Các đoạn tiếp theo cũng được phân cách bằng những dòng trống.

 - Được phép sử dụng gạch đầu dòng

 - Dấu gạch ('-' - ND) hay dấu sao ('*' - ND) có thể được dùng như gạch
   đầu dòng, bắt đầu bằng một khoảng trắng. Các gạch đầu dòng có thể
   cách nhau bởi một dòng trống hoặc không, tùy theo quy định riêng

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
# modified:   hello.rb
#
~
~
~
".git/COMMIT_EDITMSG" 25L, 884C written

Thông điệp xác nhận rất quan trọng vì sức mạnh của Git phần lớn nằm ở khả năng có thể tạo những xác nhận và sau đó chia sẻ chúng. Ba hay bốn xác nhận được phân chia một cách hợp lý sẽ giúp việc theo dõi và xem lại dễ dàng hơn. Bởi vì có sự phân chia giữa xác nhận và đẩy những chỉnh sửa này, dành thời gian viết những thông điệp xác nhận tốt sẽ giúp đồng nghiệp hiểu được bạn đang làm gì và vì sao dễ dàng hơn.

git commit -a tự động chỉ mục tất cả các tập tin đã chỉnh sửa, theo dõi trước khi xác nhận

Nếu bạn cho rằng giai đoạn git add trong chu trình làm việc là quá rườm rà, Git cho phép bỏ qua nó bằng tùy chọn -a. Với tùy chọn này, Git sẽ thực hiện git add với tất cả những tập tin đang được "tracked" (theo dõi) - tập tin đã được chỉnh sửa từ lần xác nhận trước. Nhờ vậy bạn có thể thực hiện theo một chu trình làm việc theo kiểu Subversion, chỉnh sửa tập tin và sau đó dùng lệnh git commit -a để ghi lại tất cả những chỉnh sửa. Bạn sẽ vẫn phải dùng lệnh git add để bắt đầu theo dõi những tập tin mới, tương tự như với Subversion.

$ vim hello.rb
$ git status -s
 M  hello.rb
$ git commit -m 'changes to hello file'
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified:   hello.rb
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -am 'changes to hello file'
[master 78b2670] changes to hello file
 1 files changed, 2 insertions(+), 1 deletions(-)

Chú ý rằng nếu bạn chưa chỉ mục chỉnh sửa nào mà thực hiện ngay lệnh git commit, Git sẽ xuất kết quả lệnh git status, nhắc nhở rằng chưa có chỉnh sửa nào được chỉ mục. Những phần quan trọng của thông điệp này được đánh dấu, nêu rằng không có chỉnh sửa nào đã được thêm vào để xác nhận. Nếu thêm tùy chọn -a, tất cả chỉnh sửa sẽ được chỉ mục và xác nhận đồng thời.

Đến đây ta đã hoàn thành một chu trình làm việc hoàn chỉnh - bạn thay đổi các tập tin, sau đó dùng lệnh git add để chỉ mục các thay đổi, lệnh git statusgit diff để bạn xem lại những chỉnh sửa đó, và cuối cùng lệnh git commit để thực sự ghi lại bản sao.

Tóm tắt: dùng lệnh git commit để ghi lại bản sao gồm những chỉnh sửa đã được chỉ mục. Bản sao này sau đó có thể được so sánh, chia sẻ hay hoàn lại nếu cần thiết.

docs   book git reset hoàn tác chỉnh sửa và xác nhận

Lệnh git reset có lẽ là lệnh khó hiểu nhất được viết ra nhưng nó rất hữu dụng một khi bạn bám vào nó. Có ba trường hợp được đưa ra về lệnh này hoàn toàn hữu ích.

git reset HEAD huỷ chỉ mục tập tin và đặt lại về HEAD

Trong trường hợp này, ta sẽ dùng nó để lấy lại những chỉnh sửa đã ghi nhận. Giả sử bạn đã chỉnh sửa hai tập tin và muốn lưu lại trong hai lần xác nhận riêng rẽ. Bạn nên chỉ mục và xác nhận lần lượt từng tập tin một. Nếu chẳng may bạn đã chỉ mục cả hai tập tin này, thực hiện lệnh git reset HEAD -- file. -- dùng để thông báo với Git rằng các tùy chọn đã được liệt kê hết, và sau đây sẽ là danh sách đường dẫn, nhưng phân cách giữa các tùy chọn và đường dẫn là một thói quen tốt.

Dưới đây ta sẽ chỉ mục chỉnh sửa ở hai tập tin và sau đó lần lượt lấy lại những chỉnh sửa của từng tập tin.

$ git status -s
 M README
 M hello.rb
$ git add .
$ git status -s
M  README
M  hello.rb
$ git reset HEAD -- hello.rb 
Unstaged changes after reset:
M hello.rb
$ git status -s
M  README
 M hello.rb

Bây giờ nếu bạn thực hiện lệnh git commit thì sẽ chỉ ghi lại chỉnh sửa ở tập tin README, chứ không bao gồm những chỉnh sửa chưa được chỉ mục trong tập tin hello.rb.

Khi bạn thực hiện lệnh này, thực tế là Git đã ghi đè checksum của một tập tin trong chỉ mục bằng checksum của chính tập tin đó trong lần xác nhận trước. Vì git add tính checksum của một tập tin và ghi nó vào chỉ mục, git reset HEAD ghi lại nó bằng giá trị cũ, từ đó có thể bỏ tập tin khỏi phạm vi chỉ mục.

Bạn có thể tạo một lệnh tắt git unstage bằng cách chaỵ lệnh git config --global alias.unstage "reset HEAD". Từ giờ bạn có thể sử dụng lệnh git unstage [file] để thực hiện thao tác này.

Nếu bạn không nhớ lệnh nào dùng để hủy chỉ mục chỉnh sửa, Git sẽ nhắc cho bạn trong kết quả của lệnh git status. Ví dụ khi bạn dùng lệnh git status mà không dùng tùy chọn -s sẽ được kết quả như sau:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   README
#   modified:   hello.rb
#

Git mặc định dùng tùy chọn --mixed khi bạn không thêm tùy chọn nào vào lệnh git reset. Các tùy chọn khác của lệnh này là --soft--hard.

git reset --soft moves HEAD to specified commit reference, index and staging are untouched

Việc đầu tiên git reset làm là hoàn tác xác nhận cuối và đưa các tập tin trở về vùng chỉ mục. Nếu bạn thêm tuỳ chọn --soft. Ví dụ, nếu bạn chạy lệnh git reset --soft HEAD~ (cha của HEAD), xác nhận cuối sẽ được hoàn tác và các tập tin sẽ được đưa trở lại vùng chỉ mục.

$ git status -s
M  hello.rb
$ git commit -am 'hello with a flower'
[master 5857ac1] hello with a flower
 1 files changed, 3 insertions(+), 1 deletions(-)
$ git status
# On branch master
nothing to commit (working directory clean)
$ git reset --soft HEAD~
$ git status -s
M  hello.rb

Lệnh này về cơ bản giống lệnh git commit --amend, cho phép bạn thêm các chỉnh sửa vào xác nhận trước đó.

git reset --hard unstage files AND undo any changes in the working directory since last commit

Tuỳ chọn thứ ba là dùng --hard để huỷ chỉ mục, hoàn tác mọi chỉnh sửa bạn thêm vào từ lần xác nhận cuối. Đây là tuỳ chọn nguy hiểm nhất không an toàn cho thư mục làm việc của bạn. Bất kỳ chỉnh sửa chưa xác nhận sẽ mất.

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# modified:   README
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified:   README
#
$ git reset --hard HEAD
HEAD is now at 5857ac1 hello with a flower
$ git status
# On branch master
nothing to commit (working directory clean)

Ở ví dụ trên, ta có chỉnh sửa dự kiến xác nhận và chỉnh sửa chưa chỉ mục của tập tin README. Lệnh git reset --hard đã xoá bỏ chúng và đặt lại toàn bộ về trạng thái giống lần xác nhận cuối.

Bạn có thể thay HEAD với mã SHA-1 của lần xác nhận bất ký để đặt lại về lần xác nhận đó.

Tóm tắt:, lệnh git reset HEAD dùng để hoàn tác lần xác nhận cuối, huỷ chỉ mục các tập tin bạn không muốn đưa vào lần xác nhận bản sao kế sau khi bạn đã dùng lệnh git add thêm vào. (ND: bạn có thể xem bài viết Reset Demystified để hiểu rõ hơn về lệnh reset của Git)

docs   book git rm loại bỏ tập tin ra khỏi vùng chỉ mục

Lệnh git rm sẽ loại bỏ tập tin ra khỏi vùng chỉ mục. Điểm khác biệt so với lệnh git reset HEAD ở chỗ lệnh lệnh này chỉ hoàn trả vùng chỉ mục lại trạng thái ban đầu, còn lệnh git rm không chỉ loại tập tin khỏi vùng chỉ mục mà còn xóa nó.

Theo mặc định, lệnh git rm file sẽ loại bỏ hoàn toàn tập tin đó khỏi vùng chỉ mục và đồng thời cũng xóa luôn tập tin trên đĩa cứng (thư mục hiện hành). Để giữ tập tin trong thư mục hiện hành, bạn dùng lệnh git rm --cached

git mv git rm --cached orig; mv orig new; git add new

Khác với phần lớn các hệ thống quản lý mã nguồn khác, Git không theo dõi các tập tin bị đổi tên. Thay vào đó nó chỉ theo dõi các bản sao để phát hiện những tập tin đã bị xóa và thêm vào với nội dung giống nhau, khi đó Git sẽ hiểu đây là trường hợp đổi tên. Mặc dù có lệnh git mv, nhưng nó là thừa - lệnh này chỉ đơn thuần git rm, di chuyển tập tin trên đĩa cứng và sau đó là git add tập tin mới.

Tôi ít khi dùng lệnh này để xóa tập tin. Thay vào đó chỉ cần xóa tập tin trên đĩa cứng và sau đó thực hiện lệnh git commit -a cũng sẽ giúp loại bỏ tập tin khỏi chỉ mục.

Tóm tắt:, lệnh git rm dùng để loại một tập tin nào đó khỏi sự theo dõi của Git và đồng thời cũng xóa tập tin đó khỏi thư mục hiện hành.

docs   book git stash save changes made in the current index and working directory for later

Bạn đang chỉnh sửa dang dở thì một vấn đề phát sinh cần được thêm vào ngay, chẳng hạn một bản vá khẩn cấp, nhưng bạn lại không muốn xác nhận hoặc mất các chỉnh sửa hiện tại của bạn. Lệnh git stash sẽ giải quyết vấn đề đó giúp bạn.

git stash add current changes to the stack

Cất giấu (stash) là đưa thư mục làm việc và vùng chỉ mục hiện tại vào một ngăn xếp và đưa bạn trở về trạng thái của lần xác nhận cuối.

Lệnh git stash sẽ không kèm theo các tập tin chưa theo dõi. Cũng như các bạn tạo xác nhận, bạn phải dùng lệnh git add để chỉ mục tập tin trước khi cất giấu hoặc với các các phiên bản Git từ 1.7.7 về sau, bạn có thể dùng lệnh git stash -u để cất giấu các tập tin chưa đánh phiên bản.

$ git status -s
M hello.rb
$ git stash
Saved working directory and index state WIP on master: 5857ac1 hello with a flower
HEAD is now at 5857ac1 hello with a flower
$ git status
# On branch master
nothing to commit (working directory clean)

git stash list liệt kê ngăn xếp

Đôi khi, bạn cần biết bạn đã xếp gọn những gì vào ngăn cất giấu, lệnh git stash list sẽ hiển thị một hàng danh sách của các mục cất giấu của bạn.

$ git stash list
stash@{0}: WIP on master: 5857ac1 hello with a flower

Mục cuối cùng thêm vào ngăn cất giấu được tham chiếu đến stash@{0} và tăng dần theo một.

$ vim hello.rb
$ git commit -am 'it stops raining'
[master ee2d2c6] it stops raining
1 files changed, 1 insertions(+), 1 deletions(-)
$ vim hello.rb
$ git stash
Saved working directory and index state WIP on master: ee2d2c6 it stops raining
HEAD is now at ee2d2c6 it stops raining
$ git stash list
stash@{0}: WIP on master: ee2d2c6 it stops raining
stash@{1}: WIP on master: 5857ac1 hello with a flower

git stash apply đưa mục từ kho cất giấu vào thư mục làm việc

Khi bạn đã sẵn sàng tiếp tục công việc từ khi bạn đã cất giấu, lệnh git stash apply sẽ đem các thay đổi đã cất giấu trở lại thư mục làm việc.

$ git stash apply
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified:   hello.rb
#
no changes added to commit (use "git add" and/or "git commit -a")

Mặc định, lệnh trên sẽ tái ghép mục cuối cùng, tham chiếu đến stash@{0}, vào thư mục làm việc. Bạn có thể tái ghép mục cất giấu khác bằng cách thêm vào tham chiếu trong danh sách đối số. Ví dụ, git stash apply stash@{1} sẽ tái ghép mục tham chiếu stash@{1}.

Nếu bạn muốn xóa mục khỏi ngăn cất giấu sau khi tái ghép, dùng lệnh git stash pop thay thế.

git stash drop xóa một mục khỏi danh sách cất giấu

Lệnh git stash drop sẽ xóa mục đã cất giấu. Mặc định, lệnh sẽ xóa mục cuối cùng nếu bạn không kèm theo đối số để xóa một mục xác định.

Trong ví dụ sau, chúng ta có hai mục trong danh sách cất giấu nhưng chúng ta muốn xóa mục đầu tiên được tham chiếu đến stash@{1}.

$ git stash drop stash@{1}
Dropped stash@{1} (0b1478540189f30fef9804684673907c65865d8f)

Khi đã chắc chắn hoàn tất các công việc với danh sách cất giấu, bạn có thể dùng lệnh git stash clear để xóa tất cả các mục đã cất giấu.

Tóm tắt: lệnh git stash lưu tạm vài thay đổi bạn chưa dự định xác nhận, và sẽ được tiếp tục khi bạn đã xong công việc khác.

Phân Nhánh và Tích Hợp »