No menu items!
No menu items!
More

    [Git] Phần 8 – Lệnh git reset, hủy (undo) commit, xóa commit

    1. Lý thuyết.

    Hủy commit cuối bằng lệnh git reset.

    Lệnh git reset được sử dụng để đặt lại trạng thái của repository git về một commit cụ thể. Có hai tham số chính thường được sử dụng với lệnh này là --soft và --hard.

    Git reset với tham số –soft.

    git reset --soft HEAD~1: Lệnh này sẽ đặt lại con trỏ HEAD về commit cha của commit hiện tại (commit cuối cùng). Tuy nhiên, nó không thay đổi vùng staging hoặc thư mục làm việc. Điều này có nghĩa là tất cả các thay đổi bạn đã commit sẽ được chuyển về vùng staging, cho phép bạn chỉnh sửa hoặc commit lại chúng.

    Git reset với tham số –hard.

    git reset --hard HEAD~1: Lệnh này cũng đặt lại con trỏ HEAD về commit cha, nhưng nó cũng sẽ thay đổi vùng staging và thư mục làm việc để phù hợp với commit đó. Điều này có nghĩa là tất cả các thay đổi bạn đã commit sẽ bị xóa hoàn toàn. Bạn nên cẩn thận khi sử dụng lệnh này, vì nó sẽ mất tất cả các thay đổi chưa được commit.

    Lưu ý rằng cả hai lệnh trên chỉ nên được sử dụng trên commit chưa được push lên remote repository. Nếu bạn đã push commit và sau đó sử dụng git reset để hủy bỏ nó, bạn sẽ gặp rắc rối khi cố gắng push lại.

    Một vài trường hợp dùng git reset khác.

    Hủy git add.

    git reset (không có tham số): Khi bạn thực hiện lệnh git add, các thay đổi của bạn sẽ được chuyển từ thư mục làm việc sang vùng staging, chuẩn bị cho việc commit. Nếu bạn muốn hủy việc thêm các thay đổi này vào vùng staging, bạn có thể sử dụng lệnh git reset mà không cần tham số. Lệnh này sẽ đặt lại vùng staging về trạng thái của commit cuối cùng, loại bỏ tất cả các thay đổi đã được thêm vào từ lệnh git add.

    Hủy đưa một file vào staging.

    git reset -- filename: Nếu bạn chỉ muốn hủy việc thêm một file cụ thể vào vùng staging, thay vì tất cả các thay đổi, bạn có thể sử dụng lệnh git reset kèm theo tên file. Lệnh này sẽ chỉ loại bỏ file cụ thể đó khỏi vùng staging, giữ lại tất cả các thay đổi khác.

    Ví dụ:

    git reset -- myfile.txt

    Lệnh trên sẽ hủy việc thêm myfile.txt vào vùng staging.

    2. Thực hành.

    Xóa commit cuối bằng git reset với tham số --soft.

    Quay lại ví dụ trước khi dùng lệnh git statusgit log --oneline chúng ta thấy các dữ liệu đã được commit thành công và hiện tại đang có 3 commit như dưới.

    shell> git status
    On branch main
    nothing to commit, working tree clean
    
    shell> git log --oneline
    ccbb0ef (HEAD -> main) Sua doi index
    a914557 C3 - Update, .gitignore
    17a15de C2 - Sua doi index
    248eedf C1 - Khoi tao

    Để xóa đi commit cuối cùng chúng ta sử dụng git reset với tham số --soft để chuyển dữ liệu về vùng staging.

    git reset --soft HEAD~1

    Bây giờ nếu sử dụng lệnh git log --oneline bạn chỉ thấy còn lại 3 commit và con trỏ HEAD bây giờ trỏ về commit C3 có mã hash là a914557.

    shell> git log --oneline
    a914557 (HEAD -> main) C3 - Update, .gitignore
    17a15de C2 - Sua doi index
    248eedf C1 - Khoi tao

    Nếu sử dụng lệnh git status bạn sẽ thấy có file index.html đang ở trong vùng staged.

    shell> git status
    On branch main
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            modified:   index.html

    Nếu chúng ta xem nội dung file index.html thì chúng ta vẫn thấy nội dung của commit cuối cùng.

    shell> cat index.html 
    Trang chu
    
    Chao mung ban den voi Website của toi
    
    Cap nhat index

    Sau khi xóa commit cuối thì chúng ta vẫn có thể tạo một commit khác như bình thường.

    Ví dụ mình tạo commit “C4 – Sua file index” và mình đã có 4 commit như dưới.

    shell> git commit -m"C4 - Sua file index"
    [main 3ea66b4] C4 - Sua file index
     1 file changed, 2 insertions(+)
    
    shell> git status
    On branch main
    nothing to commit, working tree clean
    
    shell> git log --oneline
    3ea66b4 (HEAD -> main) C4 - Sua file index
    a914557 C3 - Update, .gitignore
    17a15de C2 - Sua doi index
    248eedf C1 - Khoi tao

    Xóa commit cuối bằng git reset với tham số --hard.

    Lệnh git reset --hard HEAD~1 được sử dụng để đặt lại trạng thái của repository git về commit trước đó (commit cha của commit hiện tại). Tham số --hard nghĩa là nó sẽ thay đổi vùng staging và thư mục làm việc để phù hợp với commit đó, tức là tất cả các thay đổi bạn đã commit sau commit đó sẽ bị xóa hoàn toàn.

    Khi bạn thực hiện lệnh này, git sẽ thông báo về trạng thái mới của HEAD. Trong trường hợp của mình ở dưới, “HEAD is now at a914557 C3 – Update, .gitignore” nghĩa là con trỏ HEAD hiện tại đang trỏ đến commit có mã hash là a914557, với mô tả commit là “C3 – Update, .gitignore”. Điều này có nghĩa là commit cuối cùng của bạn đã bị hủy và repository đã quay trở lại trạng thái tại thời điểm commit a914557.

    shell> git reset --hard HEAD~1
    HEAD is now at a914557 C3 - Update, .gitignore

    Nếu bạn xem file index.html thì nội dung của nó đã quay về nội dung của commit thứ 3.

    shell> cat index.html 
    Trang chu
    
    Chao mung ban den voi Website của toi

    Do sử dụng tùy chọn --hard, commit sẽ bị xóa hoàn toàn và nếu bạn sử dụng git status bạn sẽ không thấy dữ liệu nào nằm trong vùng statged.

    shell> git status
    On branch main
    nothing to commit, working tree clean

    Sử dụng lệnh git log --oneline bây giờ bạn chỉ thấy 3 commit.

    shell> git log --oneline
    a914557 (HEAD -> main) C3 - Update, .gitignore
    17a15de C2 - Sua doi index
    248eedf C1 - Khoi tao

    Xóa một file ở trong vùng staged.

    Giả sử tôi thêm nội dung file index.html với nội dung như dưới.

    cat > index.html << 'OEF'
    Trang chu
    Chao mung ban den voi Website của toi
    Chao mung ban den voi Website của toi
    Chao mung ban den voi Website của toi
    OEF

    Khi bạn sử dụng lệnh git status bạn sẽ thấy file index.html này đang chưa nằm vào vùng staged.

    shell> git status
    On branch main
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            modified:   index.html
    
    no changes added to commit (use "git add" and/or "git commit -a")

    Sử dụng lệnh git add để thêm file này vào vùng staged và kiểm tra lại bằng lệnh git status bạn sẽ thấy file index.html đã nằm trong vùng staged và đã sẵn sàng để commit.

    shell> git add .
    shell> git status
    On branch main
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            modified:   index.html

    Tuy nhiên ở ví dụ này chúng ta sẽ dùng lệnh git reset để xóa file index.html trong vùng staged bằng ví dụ như dưới.

    shell> git reset -- index.html 
    Unstaged changes after reset:
    M       index.html

    Và nếu bây giờ bạn sử dụng lệnh git status bạn sẽ thấy file index.html đã bị xóa khỏi staged.

    shell> git status
    On branch main
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            modified:   index.html
    
    no changes added to commit (use "git add" and/or "git commit -a")

    Phục hồi nội dung từ vùng staged khi thêm một file vào vùng staging (với git add), sau đó tiếp tục chỉnh sửa file đó mà không thêm các thay đổi mới vào vùng staging.

    Giả sử tôi sẽ thêm 1 dòng Chao mung ban den voi Website của toi vào file index.html và tôi sẽ có 4 dòng với nội dung này.

    shell> echo -e '\nChao mung ban den voi Website của toi' >>  index.html
    
    shell> cat index.html 
    Trang chu
    Chao mung ban den voi Website của toi
    Chao mung ban den voi Website của toi
    Chao mung ban den voi Website của toi
    Chao mung ban den voi Website của toi

    Khi bạn chạy lệnh git status, git sẽ cung cấp cho bạn thông tin về trạng thái hiện tại của repository. Trong trường hợp của này, có hai phần chính trong output:

    • Changes to be committed:: Phần này liệt kê các thay đổi đã được thêm vào vùng staging và sẽ được commit khi bạn chạy lệnh git commit. Trong trường hợp của bạn, file index.html đã được sửa đổi và thay đổi đó đã được thêm vào vùng staging.
    • Changes not staged for commit:: Phần này liệt kê các thay đổi trong thư mục làm việc mà chưa được thêm vào vùng staging. Điều này có nghĩa là, nếu bạn chạy lệnh git commit ngay bây giờ, những thay đổi này sẽ không được commit. Trong trường hợp của bạn, file index.html cũng đã được sửa đổi nhưng thay đổi đó chưa được thêm vào vùng staging.

    Điều này có thể xảy ra nếu bạn đã thêm một file vào vùng staging (với git add), sau đó tiếp tục chỉnh sửa file đó mà không thêm các thay đổi mới vào vùng staging.

    shell> git status
    On branch main
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            modified:   index.html
    
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
            modified:   index.html

    Mình sử dụng lệnh git restore với tham số — và chỉ định tên file cần phục hồi nội dung hoặc dấu chấm (.) nếu phục hồi tất cả. Sau khi restore xong bạn sẽ thấy file index.html đã nằm trong vùng staged và sẵn sàng để commit.

    shell> git restore -- .
    shell> git status
    On branch main
    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
            modified:   index.html

    Trước khi commit mình sẽ kiểm tra số lượng commit và sau đó tiến hành commit.

    shell> git log --oneline
    a914557 (HEAD -> main) C3 - Update, .gitignore
    17a15de C2 - Sua doi index
    248eedf C1 - Khoi tao
    
    shell> git commit -m"C4 Update index"
    [main 0237c94] C4 Update index
     1 file changed, 2 insertions(+), 1 deletion(-)

    Commit xong mình sử dụng git status và nhận thông báo working tree clean cho biết commit đã thành công.

    shell> git status
    On branch main
    nothing to commit, working tree clean

    Sử dụng git log --oneline bạn nhận được 4 commit dưới dưới.

    shell> git log --oneline
    0237c94 (HEAD -> main) C4 Update index
    a914557 C3 - Update, .gitignore
    17a15de C2 - Sua doi index
    248eedf C1 - Khoi tao

    Bài viết gần đây

    spot_img

    Related Stories

    Leave A Reply

    Please enter your comment!
    Please enter your name here

    Đăng ký nhận thông tin bài viết qua email