Chuyển đến nội dung chính

Giải thích Git Diff: Hướng dẫn đầy đủ kèm ví dụ

Tìm hiểu cách sử dụng git diff để theo dõi thay đổi mã hiệu quả, từ so sánh cơ bản đến kỹ thuật nâng cao. Khám phá công cụ trực quan hóa, lệnh chuyên biệt và quy trình để quản lý mã tốt hơn.
Đã cập nhật 5 thg 10, 2026  · 12 phút đọc

Khám phá cùng AI

ChatGPTClaudePerplexity

Git diff là cửa sổ giúp bạn nhìn vào những thay đổi đang diễn ra trong kho mã của mình. Về cốt lõi, đây là một lệnh cho bạn thấy sự khác biệt giữa các trạng thái khác nhau của tệp — dù là so sánh công việc hiện tại với những gì bạn đã stage hay so sánh thay đổi giữa nhánh và commit. Hãy coi nó như cách Git trả lời câu hỏi “Đã thay đổi gì?” Khi bạn chạy git diff, Git phân tích nội dung tệp theo từng dòng, xác định phần nào được thêm, xóa hoặc sửa, và hiển thị thông tin này theo định dạng chuẩn làm nổi bật chính xác điều gì đã thay đổi và ở đâu.

Git diff giúp nhà phát triển đảm bảo chất lượng mã bằng cách cung cấp cái nhìn rõ ràng về các chỉnh sửa trước khi chúng được commit. Ở đây, chúng ta sẽ đề cập cách sử dụng hiệu quả lệnh thiết yếu này, từ so sánh cơ bản đến kỹ thuật nâng cao giúp cải thiện quy trình phát triển và cộng tác nhóm.

Yêu cầu tiên quyết

Để theo dõi bài hướng dẫn này, bạn nên quen với các khái niệm Git sau:

  • Quy trình Git cơ bản (init, add, commit)
  • Kho Git và cấu trúc của chúng
  • Nhánh và cách chúng hoạt động
  • Commit và lịch sử commit
  • Khu vực staging (index)

Nếu bạn cần ôn lại các khái niệm này, các tài nguyên sau sẽ hữu ích:

Bạn sẽ cần cài đặt Git trên hệ thống để thực hiện các ví dụ. Mọi lệnh đều có thể chạy trong terminal hoặc command prompt.

Vì sao Git Diff thiết yếu với nhà phát triển

Mọi nhà phát triển đều cần biết điều gì đã thay đổi trong mã của mình, dù làm việc một mình hay trong đội hàng trăm người. Không có git diff, bạn sẽ phải đoán dòng nào đã sửa, khiến việc gỡ lỗi và cộng tác gần như bất khả thi.

Git diff rất quan trọng cho quản lý thay đổi và là nền tảng xây dựng phần mềm chất lượng thông qua quy trình review hiệu quả. Khi xem xét thay đổi, git diff cung cấp ngữ cảnh cần thiết để hiểu không chỉ thay đổi gì mà còn vì sao các thay đổi đó quan trọng. 

Khả năng quan sát trực tiếp sự tiến hóa của mã giúp đội ngũ duy trì tiêu chuẩn và ngăn lỗi lọt vào môi trường sản xuất.

Khi dự án tăng độ phức tạp, git diff trở nên không thể thiếu vì nhiều lý do then chốt:

  • Xác minh thay đổi: Xác nhận chính xác những gì bạn sắp commit, tránh vô tình đưa vào mã debug hoặc thay đổi không liên quan
  • Chuyển giao kiến thức: Hiểu đồng đội đã làm gì mà không cần đọc toàn bộ tệp
  • Giải quyết xung đột: Xác định chính xác vị trí và cách thay đổi xung đột khi merge
  • Phân tích lịch sử: Truy ra khi nào những thay đổi cụ thể được đưa vào để truy lỗi hoặc hiểu sự phát triển của tính năng
  • Code review có trọng tâm: Tập trung vào phần mã thực sự thay đổi, tiết kiệm thời gian và nâng cao chất lượng review

Để dùng git diff hiệu quả, cần hiểu kiến trúc nền tảng cho phép các phép so sánh này — mô hình “Ba Cây” của Git.

Kiến trúc Ba Cây của Git

Để hiểu git diff, trước tiên bạn cần nắm mô hình “ba cây” cơ bản của Git. Dù tên gọi là vậy, đây không phải cây thực trong hệ thống tệp mà là ba trạng thái riêng biệt nơi mã của bạn tồn tại. 

Hãy coi các trạng thái này như ba phiên bản khác nhau của dự án mà Git theo dõi đồng thời: Thư mục làm việc (Working Directory — các tệp thực tế của bạn), Khu vực staging (Staging Area hay index, nơi chuẩn bị các thay đổi để commit), và Kho (Repository — lịch sử commit của dự án lưu trong thư mục .git).

Kiến trúc Ba Cây của Git hiển thị Working Directory, Staging Area và Repository

Nguồn: Hashnode

Working Directory chứa các tệp bạn đang chỉnh sửa — nơi bạn viết mã, thay đổi và thử nghiệm. Staging Area là vùng chuẩn bị nơi bạn chọn những thay đổi sẽ đưa vào commit tiếp theo. Bạn có thể hình dung nó như bến xuất hàng nơi “kiện hàng” (các thay đổi) được sắp xếp trước khi gửi đi. 

Cuối cùng, Repository lưu toàn bộ lịch sử dự án dưới dạng chuỗi commit — ảnh chụp mã tại các thời điểm cụ thể, liên kết với nhau thành một chuỗi lịch sử.

Git diff hoạt động bằng cách so sánh ba trạng thái này theo các kết hợp khác nhau. Khi bạn chạy git diff không có tham số, nó so sánh Working Directory với Staging Area, hiển thị các thay đổi bạn đã thực hiện nhưng chưa stage. 

Dùng git diff --staged để so sánh Staging Area với commit gần nhất, hiển thị những gì sẽ được đưa vào commit tiếp theo. 

Còn git diff HEAD so sánh trực tiếp Working Directory với commit gần nhất, hiển thị mọi thay đổi chưa commit bất kể đã stage hay chưa.

Những điểm so sánh này tạo nền tảng cho mọi hoạt động diff trong Git:

  • Working Directory ↔ Staging Area: Tôi đã thay đổi gì nhưng chưa stage? (git diff)
  • Staging Area ↔ Repository: Tôi đã stage những gì sẽ được commit tiếp theo? (git diff --staged)
  • Working Directory ↔ Repository: Tổng khác biệt giữa tệp đang làm và commit gần nhất là gì? (git diff HEAD)
  • Giữa các commit: Mã đã tiến hóa thế nào giữa các mốc lịch sử cụ thể? (git diff commit1-hash commit2-hash)

Hiểu kiến trúc này giúp bạn có mô hình tư duy để dùng git diff hiệu quả nhằm xác định chính xác điều gì đã thay đổi, ở đâu và khi nào trong codebase.

Với nền tảng kiến trúc đã rõ, giờ ta có thể khám phá cách dùng các lệnh git diff trong thực tế để nắm bắt sự tiến hóa của mã qua ba trạng thái này.

Cách dùng Git Diff cơ bản

Hãy tạo một dự án phân tích dữ liệu mẫu để minh họa git diff. Chúng ta sẽ thiết lập một kho nhỏ với script Python, dữ liệu CSV và tệp văn bản để chỉnh sửa xuyên suốt hướng dẫn.

# Create and initialize our project
mkdir data-analysis-project
cd data-analysis-project
git init

# Create initial files
echo "# Data Analysis Project\nA sample project to demonstrate git diff functionality." > README.md
echo "import pandas as pd\n\ndef load_data(filename):\n return pd.read_csv(filename)\n\ndef analyze_data(data):\n return data.describe()" > analysis.py
echo "id,name,value\n1,alpha,10\n2,beta,20\n3,gamma,30" > data.csv
echo "DEBUG=False\nDATABASE_PATH=./data/" > config.txt
echo "def normalize_data(data):\n return (data - data.min()) / (data.max() - data.min())" > utils.py

# Make our first commit
git add .
git commit -m "Initial commit with basic project structure"

# Check the directory structure
> tree

.
├── README.md
├── analysis.py
├── config.txt
├── data.csv
└── utils.py

Dự án của chúng ta hiện có năm tệp dưới quản lý phiên bản, tạo nền tảng để minh họa các kịch bản diff khác nhau. Khi tiến hành, chúng ta sẽ chỉnh sửa những tệp này để cho thấy git diff hiển thị thay đổi trong các ngữ cảnh khác nhau như thế nào.

Hiểu kết quả của git diff

Khi bạn chạy một lệnh git diff, đầu ra tuân theo định dạng chuẩn được thiết kế để chỉ rõ điều gì đã thay đổi. Hãy sửa tệp analysis.py để xem diff hoạt động:

# Update analysis.py with a new function
echo "import pandas as pd\n\ndef load_data(filename):\n return pd.read_csv(filename)\n\ndef analyze_data(data):\n return data.describe()\n\ndef visualize_data(data):\n return data.plot(kind='bar')" > analysis.py

Giờ hãy xem git diff tạo ra:

git diff

Bạn sẽ thấy đầu ra tương tự như sau:

Đầu ra ví dụ của lệnh git diff

Lưu ý: Để thoát khỏi màn hình git diff, nhấn “q” trong terminal.

Hãy phân tích đầu ra này:

  1. Phần đầu (diff --git a/analysis.py b/analysis.py) cho biết tệp nào đang được so sánh, ở đây là analysis.py
  2. Phần siêu dữ liệu tệp (index db0e049..a7a7ab0 100644) hiển thị các định danh nội bộ của Git cho phiên bản trước và sau
  3. Các đánh dấu tệp (--- a/analysis.py and +++ b/analysis.py) biểu thị tệp “trước” và “sau”
  4. Phần tiêu đề hunk (@@ -5,3 +5,6 @@) cho biết những dòng nào bị ảnh hưởng. Cách đọc như sau:
  • -5,3 nghĩa là bắt đầu từ dòng 5 trong tệp gốc, 3 dòng được hiển thị trong diff
  • +5,6 nghĩa là bắt đầu từ dòng 5 trong tệp đã sửa, 6 dòng được hiển thị trong diff
  • Chênh lệch giữa các con số này cho thấy đã có 3 dòng được thêm

5. Phần nội dung thay đổi với những dòng bắt đầu bằng + thể hiện nội dung được thêm

Trong các tệp lớn, git diff gom thay đổi thành “hunk” — các đoạn chứa thay đổi. Mỗi hunk có tiêu đề riêng với số dòng để giúp bạn xác định vị trí thay đổi trong tệp.

So sánh thư mục làm việc và khu vực staging

Chạy git diff không tham số sẽ so sánh Working Directory (trạng thái hiện tại của tệp) với Staging Area (các thay đổi sẵn sàng commit). Điều này hữu ích để rà soát những gì bạn đã sửa nhưng chưa chuẩn bị cho commit tiếp theo.

Hãy sửa nhiều tệp để minh họa:

# Update README.md
echo "# Data Analysis Project\nA sample project to demonstrate git diff functionality.\n\n## Installation\nRun \pip install -r requirements.txt" > README.md

# Update data.csv
echo "id,name,value\n1,alpha,10\n2,beta,20\n3,gamma,30\n4,delta,40" > data.csv

Giờ hãy chỉ stage thay đổi ở README.md:

git add README.md

Chạy git diff lúc này sẽ chỉ hiển thị những thay đổi chưa stage ở data.csv và tệp analysis.py phía trên:

Đầu ra mẫu của lệnh git diff

Điều này giúp bạn tập trung vào phần chưa stage. Nếu muốn xem những gì đã stage:

git diff --staged # hoặc git diff --cached (chúng đồng nghĩa)

Đầu ra của lệnh git diff

Lệnh này sẽ hiển thị các thay đổi ở README.md đã được stage và sẵn sàng commit. Quy trình này rất quan trọng để tạo ra các commit sạch và hợp lý. Bạn có thể stage những phần công việc liên quan với nhau, xem diff của phần đã stage để xác nhận đó là một đơn vị thay đổi mạch lạc, rồi mới commit.

So sánh khu vực staging và commit gần nhất

Lệnh git diff --staged so sánh Staging Area với commit gần nhất. Điều này cho bạn thấy chính xác những gì sẽ được đưa vào commit tiếp theo nếu bạn chạy git commit ngay bây giờ.

Hãy stage thay đổi ở data.csv và xem những gì đã stage:

git add data.csv
git diff --staged

Đầu ra bây giờ sẽ hiển thị thay đổi ở cả README.md và data.csv, vì cả hai đều đã được stage. Bước rà soát này rất quan trọng trước khi commit — nó là tuyến phòng thủ cuối cùng chống lại việc commit những thay đổi không mong muốn.

Một quy trình điển hình có thể như sau:

  1. Thực hiện thay đổi trên nhiều tệp
  2. Chạy git diff để rà soát tất cả thay đổi
  3. Dùng git add <file> có chọn lọc để stage các nhóm thay đổi hợp lý
  4. Chạy git diff --staged để xác minh nội dung sắp commit
  5. Commit phần đã stage với git commit -m "Your message"
  6. Lặp lại cho các nhóm thay đổi hợp lý khác

Cách làm có hệ thống này giúp duy trì lịch sử commit sạch và có ý nghĩa, dễ hiểu quá trình dự án phát triển và xác định nơi có thể phát sinh vấn đề. Khi có kinh nghiệm, các lệnh diff này sẽ trở thành phản xạ tự nhiên, là “bạn đồng hành” thường trực trong quá trình phát triển.

Hãy thực hiện các commit trước khi chuyển sang giai đoạn tiếp theo:

# data.csv and README.md are to be committed
git commit -m "Modify data.csv and README.md files"

# Stage and commit analysis.py
git add analysis.py
git diff --staged  # Review the changes one more time
git commit -m "Add a new function to analysis.py"

Kỹ thuật Git Diff trung cấp

Giờ khi đã hiểu các kiến thức cơ bản về git diff, hãy khám phá những kỹ thuật mạnh hơn giúp bạn theo dõi và phân tích thay đổi trong dự án tốt hơn. Chúng ta sẽ tiếp tục làm việc với dự án phân tích dữ liệu để minh họa các khái niệm trung cấp này.

So sánh giữa các tham chiếu khác nhau

Git được xây dựng quanh khái niệm tham chiếu — con trỏ trỏ tới trạng thái cụ thể của mã. Các tham chiếu này bao gồm nhánh, commit và tag. Lệnh git diff có thể so sánh bất kỳ hai tham chiếu nào để hiển thị những thay đổi giữa chúng.

Hãy tạo một nhánh mới để phát triển tính năng và thực hiện một vài thay đổi:

# Create and switch to a new branch
git checkout -b feature/advanced-analytics

# Modify the analysis.py file with a new function
echo "import pandas as pd
import numpy as np

def load_data(filename):
   return pd.read_csv(filename)

def analyze_data(data):
   return data.describe()

def visualize_data(data):
   return data.plot(kind='bar')

def perform_advanced_analysis(data):
   """Performs advanced statistical analysis on the dataset"""
   results = {}
   results['correlation'] = data.corr()
   results['skew'] = data.skew()
   return results" > analysis.py

# Commit the changes
git add analysis.py
git commit -m "Add advanced analysis function"

Giờ chúng ta có thể so sánh nhánh tính năng với nhánh main:

git diff main feature/advanced-analytics

Lệnh này hiển thị mọi khác biệt giữa hai nhánh — mọi tệp đã được sửa, thêm hoặc xóa. Bạn sẽ thấy các thay đổi ở analysis.py, bao gồm import mới và hàm mới (nhấn Enter nhiều lần vì toàn bộ diff có thể bị cắt ngắn trong terminal).

Để so sánh với một commit cụ thể, bạn có thể dùng hash của commit:

git log --oneline  # Tìm commit hash bạn muốn so sánh

Đầu ra của lệnh git log --oneline

git diff 7b3105e  # Thay 7b3105e bằng hash commit thực tế bạn muốn so sánh

Khả năng so sánh này trở nên vô giá khi:

  • Chuẩn bị cho code review bằng cách xem tất cả thay đổi trong một nhánh tính năng
  • Kiểm tra những thay đổi nhánh của đồng nghiệp sẽ đưa vào trước khi merge
  • Hiểu cách codebase tiến hóa giữa các bản phát hành hoặc phiên bản

So sánh các tệp cụ thể

Khi làm việc với kho lớn, bạn thường muốn tập trung vào thay đổi của các tệp hoặc thư mục cụ thể thay vì xem tất cả khác biệt. Git diff cho phép bạn chỉ định đường dẫn rất dễ dàng.

Hãy thay đổi nhiều tệp:

# Update config.txt
echo "DEBUG=True
DATABASE_PATH=./data/
LOG_LEVEL=INFO" > config.txt

# Update utils.py
echo "def normalize_data(data):
   return (data - data.min()) / (data.max() - data.min())

def clean_data(data):
   return data.dropna()" > utils.py

Để chỉ xem thay đổi của tệp cấu hình:

git diff config.txt

Hoặc so sánh một tệp cụ thể giữa các nhánh:

# So sánh tệp analysis.py giữa nhánh main và feature/advanced-analytics
git diff main feature/advanced-analytics -- analysis.py

Dấu -- trong lệnh trên giúp Git phân biệt giữa tham chiếu và đường dẫn tệp. Điều này đặc biệt hữu ích khi:

  • Làm việc trong kho có nhiều tệp nhưng tập trung vào thành phần cụ thể (thường xuyên xảy ra)
  • Kiểm tra cấu hình thay đổi như thế nào giữa các nhánh
  • Rà soát chỉ những tệp quan trọng nhất trong một tập thay đổi lớn

Các tùy chọn diff theo ngữ cảnh

Git diff cung cấp nhiều tùy chọn điều chỉnh cách hiển thị khác biệt, giúp bạn tập trung vào những thay đổi có ý nghĩa.

Chẳng hạn, khi xử lý thay đổi định dạng mã, khác biệt về khoảng trắng có thể che mất thay đổi quan trọng về ngữ nghĩa. Hãy minh họa với một thay đổi định dạng:

# Make a whitespace change to analysis.py
sed -i '' 's/    return/  return/g' analysis.py  # Reduce indentation

Giờ, so sánh bằng git diff tiêu chuẩn sẽ hiển thị thay đổi khoảng trắng (chú ý các câu lệnh return bị lệch hàng):

git diff analysis.py

# OUT:
--- a/analysis.py
+++ b/analysis.py
@@ -2,17 +2,17 @@ import pandas as pd
import numpy as np

def load_data(filename):
-    return pd.read_csv(filename)
+  return pd.read_csv(filename)

def analyze_data(data):
-    return data.describe()
+  return data.describe()

def visualize_data(data):
-    return data.plot(kind='bar')
+  return data.plot(kind='bar')

def perform_advanced_analysis(data):
    Performs advanced statistical analysis on the dataset
    results = {}
    results['correlation'] = data.corr()
    results['skew'] = data.skew()
-    return results
+  return results

Nhưng chúng ta có thể bỏ qua thay đổi khoảng trắng (lệnh dưới đây sẽ không hiển thị thay đổi vì ta chỉ bỏ khoảng trắng):

git diff -w analysis.py  # hoặc --ignore-all-space

Một tùy chọn hữu ích khác là điều khiển số dòng ngữ cảnh — các dòng không đổi hiển thị xung quanh phần sửa đổi:

git diff -U1 analysis.py  # Chỉ hiển thị 1 dòng ngữ cảnh (mặc định là 3)
git diff -U5 analysis.py  # Hiển thị 5 dòng ngữ cảnh

Các tùy chọn ngữ cảnh này đặc biệt hữu ích khi:

  • Rà soát mã đã qua công cụ định dạng tự động
  • Tập trung vào thay đổi chức năng thay vì thay đổi phong cách
  • Cần nhiều ngữ cảnh hơn để hiểu một thay đổi cụ thể
  • Làm việc với tệp lớn nơi ngữ cảnh mặc định tạo ra quá nhiều đầu ra

Thành thạo các kỹ thuật trung cấp này giúp bạn kiểm soát tốt hơn cách rà soát và hiểu thay đổi trong codebase, làm quy trình phát triển hiệu quả hơn và code review chất lượng hơn.

Hãy commit các thay đổi mới nhất trước khi chuyển sang các ứng dụng git diff nâng cao:

git add .
git commit -m "Modify analysis.py, config.txt, and utils.py"

Ứng dụng Git Diff nâng cao

Dựa trên hiểu biết về các kỹ thuật trung cấp của git diff, hãy khám phá một số ứng dụng nâng cao đưa kỹ năng Git của bạn lên tầm mới. Những kỹ thuật này đặc biệt hữu ích khi làm việc với codebase phức tạp hoặc cộng tác trong đội lớn.

Sử dụng công cụ diff bên ngoài

Dù diff tích hợp của Git mạnh mẽ, đôi khi công cụ diff trực quan sẽ rõ ràng hơn, nhất là với thay đổi phức tạp. Git cho phép bạn cấu hình công cụ bên ngoài để nâng cao trải nghiệm diff.

Hãy thiết lập một công cụ diff trực quan phổ biến. Chúng ta dùng VSCode làm ví dụ, nhưng cấu hình tương tự cũng áp dụng cho Beyond Compare, Meld hoặc KDiff3:

# Configure Git to use VSCode as the diff tool (project-specific)
git config diff.tool vscode
git config difftool.vscode.cmd "code --wait --diff \$LOCAL \$REMOTE"

# To use other popular tools, you could use:
# For Beyond Compare (project-specific):
git config diff.tool bc3
git config difftool.bc3.path "/path/to/beyond/compare"

# Installation commands:
# For Beyond Compare:
# On macOS: brew install --cask beyond-compare
# On Ubuntu: sudo apt-get install beyond-compare
# On Windows: Download from https://www.scootersoftware.com/download.php

# Note: To apply these settings globally instead of just the current project,
# add the --global flag to each command, for example:
# git config --global diff.tool vscode

Giờ thay vì dùng git diff, bạn có thể dùng:

git difftool main feature/advanced-analytics

Lệnh này sẽ mở công cụ diff trực quan đã cấu hình để hiển thị thay đổi. Dưới đây là giao diện Beyond Compare:

Giao diện công cụ git diff Beyond Compare

Các công cụ diff trực quan mang lại nhiều lợi thế:

  1. So sánh song song giúp dễ thấy ngữ cảnh
  2. Tô sáng cú pháp phù hợp với tùy chỉnh trình soạn thảo của bạn
  3. Điều hướng nâng cao giữa các thay đổi
  4. Có thể chỉnh sửa tệp trực tiếp khi đang xem khác biệt

Khi rà soát thay đổi lớn hoặc tệp có cấu trúc phức tạp (như JSON hoặc XML lồng nhau), công cụ diff trực quan có thể cải thiện đáng kể khả năng hiểu và hiệu suất.

Các lệnh diff chuyên biệt

Git cung cấp các lệnh diff chuyên biệt cho phép bạn kiểm soát chi tiết hơn trong các trường hợp cụ thể. Hãy khám phá một số lệnh mạnh mẽ sau:

git diff-tree kiểm tra khác biệt giữa các đối tượng tree (thư mục):

# Get the hash of the last two commits
LAST_COMMIT=$(git rev-parse HEAD)
PREV_COMMIT=$(git rev-parse HEAD~1)

# Show changes in the last commit
git diff-tree --patch $PREV_COMMIT $LAST_COMMIT

git diff-index so sánh cây làm việc với index (khu vực staging) hoặc một tree:

# Compare working directory with the index
git diff-index --patch HEAD

git diff-index đặc biệt hữu ích cho scripting và tự động hóa. Nó cho phép bạn kiểm tra theo chương trình những thay đổi nào sẽ được đưa vào commit tiếp theo, rất giá trị cho pre-commit hook và script kiểm tra.

Ví dụ, bạn có thể dùng nó trong pipeline CI/CD để xác minh rằng một số tệp không bị sửa hoặc đảm bảo thay đổi cấu hình tuân theo mẫu nhất định trước khi cho phép commit.

git diff-files hiển thị thay đổi giữa các tệp trong Working Directory và index:

# Check differences for specific files
git diff-files --patch config.txt

Các lệnh chuyên biệt này đặc biệt hữu ích cho:

  • Tạo workflow và script Git tùy biến
  • Gỡ lỗi các vấn đề nội bộ của Git
  • Phân tích có mục tiêu trạng thái kho
  • Xây dựng công cụ tự động hóa tương tác với Git

Phân tích lịch sử mã

Một trong những ứng dụng mạnh nhất của git diff là phân tích cách mã đã tiến hóa theo thời gian, rất quan trọng khi gỡ lỗi hoặc hiểu sự phát triển của tính năng.

Hãy xem một commit cụ thể bằng cú pháp đặc biệt ^!:

# Get the hash of our advanced analytics commit
ANALYTICS_COMMIT=$(git log --oneline | grep "advanced analysis" | cut -d ' ' -f 1)

# Show only changes introduced in that specific commit
git diff $ANALYTICS_COMMIT^!

Cú pháp ^! là viết tắt cho so sánh một commit với cha của nó, hiển thị chính xác những gì thay đổi chỉ trong commit đó.

Để lần theo cách một tệp cụ thể đã tiến hóa theo thời gian:

# Analyze how analysis.py changed over the last 3 commits
git log -p -3 analysis.py

Khi truy tìm lỗi, bạn có thể dùng git diff với git bisect:

# Add a bug to simulate a regression
echo "import pandas as pd
import numpy as np

def load_data(filename):
   # Bug: accidentally returning None instead of the data
   pd.read_csv(filename)
   return None

def analyze_data(data):
   return data.describe()

def visualize_data(data):
   return data.plot(kind='bar')

def perform_advanced_analysis(data):
   results = {}
   results['correlation'] = data.corr()
   results['skew'] = data.skew()
   return results" > analysis.py

git add analysis.py
git commit -m "Update analysis.py with a hidden bug"

# Now use git bisect to find when the bug was introduced
git bisect start
git bisect bad  # Mark current commit as containing the bug
git bisect good main  # Mark the main branch as working correctly

# Git will check out commits for you to test
# Once found, you can examine the exact change that introduced the bug
git diff HEAD^!

Git bisect là công cụ gỡ lỗi mạnh mẽ thực hiện tìm kiếm nhị phân trong lịch sử commit để tìm commit đưa lỗi vào. Kết hợp với git diff, nó tạo ra một quy trình hiệu quả:

1. Bắt đầu quá trình bisect với git bisect start

2. Đánh dấu commit hiện tại là bad (chứa lỗi) bằng git bisect bad

3. Đánh dấu một commit tốt đã biết (không có lỗi) bằng git bisect good <commit-hash>

4. Git tự động checkout một commit ở giữa lịch sử để bạn kiểm tra.

5. Sau khi kiểm tra commit hiện tại, thông báo cho git kết quả:

  • Nếu lỗi tồn tại ở commit này: git bisect bad
  • Nếu lỗi không tồn tại ở commit này: git bisect good

6. Git sẽ tiếp tục checkout các commit khác dựa trên phản hồi của bạn (sau mỗi lệnh git bisect bad/good), thu hẹp phạm vi mỗi lần. Lặp lại kiểm tra và đánh dấu cho đến khi git xác định commit xấu đầu tiên.

7. Khi git tìm thấy commit có vấn đề, nó sẽ hiển thị thông báo cho biết commit nào đã đưa lỗi vào.

8. Xem chính xác điều gì thay đổi trong commit đó bằng: git diff HEAD^!

9. Lệnh này cho bạn thấy chính xác đoạn mã được sửa trong commit đã đưa lỗi vào, cho phép bạn tập trung gỡ lỗi vào những thay đổi cụ thể đó.

10. Thoát bisect bất cứ lúc nào với: git bisect reset Lệnh này sẽ đưa bạn về nhánh trước khi bắt đầu bisect.

11. Bạn cũng có thể tự động hóa quá trình bisect với: git bisect run <test-script> Trong đó là lệnh trả về 0 với commit tốt và khác 0 với commit xấu.

Quy trình này rút ngắn đáng kể thời gian gỡ lỗi, đặc biệt trong codebase lớn với nhiều commit giữa trạng thái hoạt động và hỏng.

Những kỹ thuật phân tích lịch sử này vô cùng hữu ích cho:

  • Tìm thời điểm và lý do lỗi được đưa vào
  • Hiểu sự tiến hóa của một tính năng hoặc thành phần
  • Kiểm tra thay đổi phục vụ đánh giá bảo mật
  • Ghi lại quá trình ra quyết định đằng sau các thay đổi mã

Thành thạo các ứng dụng git diff nâng cao này, bạn sẽ điều hướng lịch sử dự án chính xác hơn, gỡ lỗi hiệu quả hơn và có cái nhìn sâu hơn về sự tiến hóa của codebase.

Tham khảo lệnh Git Diff

Git diff cung cấp nhiều tùy chọn để tùy biến đầu ra và hành vi cho các tình huống cụ thể. Dưới đây là phần tham khảo toàn diện về các tham số thường dùng nhất để tăng cường phân tích khác biệt:

Tùy chọn so sánh cơ bản

  • git diff - So sánh Working Directory với Staging Area
  • git diff --staged (hoặc --cached) - So sánh Staging Area với commit gần nhất
  • git diff HEAD - So sánh Working Directory với commit gần nhất
  • git diff <commit> - So sánh Working Directory với commit cụ thể
  • git diff <commit1> <commit2> - So sánh hai commit cụ thể
  • git diff <branch1> <branch2> - So sánh hai nhánh

Giới hạn theo đường dẫn

  • git diff -- <path> - Giới hạn so sánh cho tệp hoặc thư mục cụ thể
  • git diff --stat - Hiển thị tóm tắt thay đổi (tệp thay đổi, số dòng thêm, xóa), rất hữu ích cho diff lớn
  • git diff --name-only - Chỉ hiển thị tên tệp thay đổi
  • git diff --name-status - Hiển thị tên và trạng thái (thêm, sửa, xóa) của tệp thay đổi

Điều khiển hiển thị

  • git diff -w (hoặc --ignore-all-space) - Bỏ qua thay đổi khoảng trắng
  • git diff --ignore-space-change - Bỏ qua thay đổi về số lượng khoảng trắng
  • git diff --color-words - Hiển thị khác biệt theo từ với màu sắc
  • git diff --word-diff - Hiển thị khác biệt theo từ ở định dạng khác
  • git diff -U<n> - Hiển thị n dòng ngữ cảnh (mặc định là 3)
  • git diff --no-prefix - Không hiển thị tiền tố a/ và b/ trong đầu ra diff

Lọc nội dung

  • git diff --binary - Hiển thị thay đổi với tệp nhị phân
  • git diff -S<string> - Tìm các thay đổi thêm hoặc xóa chuỗi chỉ định
  • git diff -G<regex> - Tìm các thay đổi khớp với biểu thức chính quy chỉ định
  • git diff --pickaxe-all - Khi dùng -S hoặc -G, hiển thị tất cả thay đổi trong tệp, không chỉ phần khớp

Tùy chọn định dạng

  • git diff --patch-with-stat - Hiển thị patch và tóm tắt thống kê
  • git diff --compact-summary - Hiển thị tóm tắt thống kê dạng gọn
  • git diff --numstat - Hiển thị thống kê ở định dạng thân thiện với máy
  • git diff --summary - Hiển thị tóm tắt tạo/xóa tệp

Bạn có thể kết hợp các tùy chọn này để tạo so sánh mạnh mẽ, có mục tiêu. Ví dụ, để xem thay đổi theo từ trong một tệp cụ thể đồng thời bỏ qua khoảng trắng:

git diff --color-words -w -- analysis.py

Hoặc để tìm tất cả nơi một hàm cụ thể có thể đã được thêm hoặc xóa:

git diff -S"def perform_advanced_analysis" main feature/advanced-analytics

Hiểu các tùy chọn này giúp bạn loại bỏ nhiễu và tập trung chính xác vào thay đổi quan trọng, làm cho quy trình rà soát và phân tích mã hiệu quả hơn. Dù bạn đang truy lỗi, chuẩn bị pull request, hay chỉ cố hiểu điều gì đã thay đổi, lựa chọn git diff phù hợp sẽ giúp công việc dễ dàng hơn nhiều.

Kết luận

Xuyên suốt bài viết, chúng ta đã khám phá git diff như một lệnh linh hoạt để xem thay đổi mã. Chúng ta đã đề cập việc so sánh tệp đang làm với thay đổi đã stage, xem khác biệt giữa nhánh và commit, và dùng các lệnh chuyên biệt để có góc nhìn sâu hơn. Tích hợp git diff vào quy trình làm việc giúp tạo commit sạch hơn, phát hiện vấn đề sớm và hỗ trợ code review tốt hơn. 

Dù làm việc cá nhân hay theo nhóm, thành thạo git diff giúp bạn không chỉ viết mã mà còn hiểu cách codebase tiến hóa theo thời gian.

Để tiếp tục nâng cao kỹ năng Git, hãy xem các tài nguyên giá trị sau: 

Những tài nguyên này sẽ giúp bạn phát triển thêm dựa trên những gì đã học về git diff và nâng tầm kỹ năng quản lý phiên bản.

Git Diff FAQs

Sự khác biệt giữa git diff và git diff --staged là gì?

git diff hiển thị các thay đổi giữa Working Directory và Staging Area (các thay đổi chưa stage), trong khi git diff --staged hiển thị các thay đổi giữa Staging Area và commit gần nhất (những gì sẽ được commit tiếp theo).

Làm thế nào để so sánh thay đổi giữa hai nhánh?

Dùng git diff branch1 branch2 để xem tất cả khác biệt giữa các nhánh. Để so sánh tệp cụ thể, thêm -- path/to/file sau tên nhánh.

Làm sao để bỏ qua thay đổi khoảng trắng trong git diff?

Dùng git diff -w hoặc git diff --ignore-all-space để bỏ qua tất cả thay đổi khoảng trắng, giúp tập trung vào khác biệt có ý nghĩa thay vì định dạng.

Tôi có thể dùng git diff để tìm khi nào một thay đổi cụ thể được đưa vào không?

Có! Dùng git diff -S"search string" để tìm khi văn bản được thêm/xóa, hoặc kết hợp với git log -p để xem sự tiến hóa của đoạn mã cụ thể. Để truy lỗi chính xác, git bisect kết hợp diff rất mạnh.

Làm thế nào để xem git diff theo cách trực quan hơn?

Cấu hình công cụ diff bên ngoài với git config diff.tool <toolname> để dùng các ứng dụng diff trực quan như VSCode, Beyond Compare hoặc Meld, cung cấp so sánh song song với khả năng trực quan tốt hơn.


Bexruz (Bex) Tuychiev's photo
Author
Bexruz (Bex) Tuychiev
LinkedIn

Tôi là người sáng tạo nội dung về khoa học dữ liệu với hơn 2 năm kinh nghiệm và là một trong những tài khoản có lượng người theo dõi lớn nhất trên Medium. Tôi thích viết các bài chuyên sâu về AI và ML với chút giọng điệu mỉa mai, vì bạn cũng phải làm gì đó để chúng bớt khô khan. Tôi đã xuất bản hơn 130 bài viết và một khóa học trên DataCamp, cùng với một khóa nữa đang được thực hiện. Nội dung của tôi đã được hơn 5 triệu lượt xem, trong đó 20 nghìn người đã trở thành người theo dõi trên cả Medium và LinkedIn. 

Chủ đề
Git
Kỹ thuật Dữ liệu

Các khóa học hàng đầu trên DataCamp

Khóa học

Git nâng cao

2 giờ
44.5K
Khám phá các nhánh và kho lưu trữ từ xa để kiểm soát phiên bản trong các dự án phần mềm và dữ liệu cộng tác bằng Git!
Xem chi tiếtRight Arrow
Bắt Đầu Khóa Học
Xem thêmRight Arrow
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem ThêmXem Thêm