Làm thế nào để so sánh các tập tin từ hai chi nhánh khác nhau?


1538

Tôi có một kịch bản hoạt động tốt trong một chi nhánh và bị hỏng ở một chi nhánh khác. Tôi muốn nhìn vào hai phiên bản cạnh nhau và xem những gì khác nhau. Có cách nào để làm điều này?

Để rõ ràng, tôi không tìm kiếm một công cụ so sánh (tôi sử dụng Beyond So sánh). Tôi đang tìm kiếm một lệnh git diff cho phép tôi so sánh phiên bản chính với phiên bản nhánh hiện tại của mình để xem những gì đã thay đổi. Tôi không ở giữa một sự hợp nhất hoặc bất cứ điều gì. Tôi chỉ muốn nói một cái gì đó như

git diff mybranch/myfile.cs master/myfile.cs

Câu trả lời:


2208

git diff có thể cho bạn thấy sự khác biệt giữa hai cam kết:

git diff mybranch master -- myfile.cs

Hoặc, tương đương:

git diff mybranch..master -- myfile.cs

Sử dụng cú pháp sau, nếu một trong hai bên HEADcó thể bị bỏ qua (ví dụ master..so sánh mastervới HEAD).

Bạn cũng có thể quan tâm mybranch...master(từ git difftài liệu ):

Hình thức này là để xem các thay đổi trên nhánh chứa và lên đến lần thứ hai <commit>, bắt đầu từ một tổ tiên chung của cả hai <commit>. git diff A...Btương đương với git diff $(git-merge-base A B) B.

Nói cách khác, điều này sẽ tạo ra sự khác biệt về những thay đổi mastervì nó được chuyển hướng từ mybranch(nhưng không có thay đổi mới kể từ đó mybranch).


Trong mọi trường hợp, --dấu phân cách trước tên tệp cho biết kết thúc cờ dòng lệnh. Đây là tùy chọn trừ khi Git sẽ bị nhầm lẫn nếu đối số đề cập đến một cam kết hoặc một tệp, nhưng bao gồm nó không phải là một thói quen xấu. Xem https://stackoverflow.com/a/13321491/54249 để biết một vài ví dụ.


Các đối số tương tự có thể được chuyển đến git difftoolnếu bạn có một cấu hình.


44
Và nếu cả hai phiên bản bạn muốn so sánh là cây công việc, bạn có thể sử dụng git diff branch1 branch2 myfile.cs. ( --Không cần thiết nữa, vì nó chỉ có thể mất tối đa hai đối số sửa đổi.)
Cascabel

8
Tôi đã thử mọi phiên bản này và không có gì xảy ra. Tôi đã cấu hình Difftool của mình (nó hoạt động để hợp nhất). Tôi có một tập tin gọi là bd.ps1. Mỗi phiên bản của lệnh tôi gõ không làm gì cả. Thậm chí không cung cấp cho một lỗi. WTH!?!?!
Mi-chê

3
@Micah: Bạn có đang thử nó với diff diff không? Bạn đang gõ đúng đường dẫn liên quan đến thư mục hiện tại? (Nó sẽ âm thầm hiển thị không có khác biệt nếu tệp không tồn tại và bạn sử dụng --. Lỗi phổ biến và dễ mắc phải.)
Cascabel

5
Điều này không hiệu quả với tôi trừ khi tôi bao gồm đường dẫn đầy đủ đến tệp, như được hiển thị bởi git diff --name-status branch1..branch2(có thể rõ ràng, nhưng tôi nghĩ tôi sẽ đề cập đến nó trong trường hợp người khác gặp rắc rối tương tự tôi đã làm).
hBrent

4
Thứ tự của mybranch và master cũng rất quan trọng. Tệp trong nhánh đầu tiên sẽ được hiển thị với tiền tố '-', tệp trong nhánh thứ hai sẽ được hiển thị với tiền tố '+'.
timbo

414

Bạn có thể làm được việc này: git diff branch1:path/to/file branch2:path/to/file

Nếu bạn đã cấu hình Difftool, thì bạn cũng có thể: git difftool branch1:path/to/file branch2:path/to/file

Câu hỏi liên quan: Làm cách nào để tôi xem git diff output với chương trình diff diff


4
Sử dụng dấu hai chấm không thực sự là một cách tuyệt vời - điều đó có nghĩa là bạn đang tham chiếu các tệp thông qua các đối tượng cây, vì vậy bạn phải nhập đường dẫn đầy đủ, thay vì liên quan đến thư mục hiện tại của bạn.
Cascabel

13
@Jefromi, điều này có thể đã thay đổi trong phiên bản mới hơn, nhưng ít nhất bây giờ bạn có thể sử dụng các đường dẫn tương đối (ví dụ branch1:./file). Điều này cũng hữu ích nếu tệp nằm ở một vị trí riêng giữa các nhánh (ví dụ git diff branch1:old/path/to/file branch2:new/path/to/file).
redbmk

4
@redbmk Vâng, đó là vào khoảng giữa năm 2010 và bây giờ! Tuy nhiên, nếu đó là cùng một tệp trên cả hai nhánh, không cần phải làm như thế này, chỉ cần git diff branch1 branch2 path/to/file.
Cascabel

3
@jefromi tuyệt vời, tôi không chắc chắn dòng thời gian khi nó được thêm vào. Vâng, tôi thường sử dụng cú pháp mà bạn đã đề cập, nhưng câu trả lời của Tim đã giúp tôi tìm ra cách so sánh các tệp với các đường dẫn khác nhau, mặc dù đó không thực sự là câu hỏi đang hỏi
redbmk 17/03/2016

1
Trong khi tôi thích ý tưởng này, tôi không thể sử dụng cú pháp này để làm việc hoặc tìm thấy bất kỳ đề cập nào về nó trong các tài liệu git diff. Tôi đang thiếu gì? Cảm ơn!
yoyo

160

Cú pháp hiện đại hơn:

git diff ..master path/to/file

Tiền tố hai chấm có nghĩa là "từ thư mục làm việc hiện tại đến". Bạn cũng có thể nói:

  • master.., tức là mặt trái của ở trên. Điều này giống như master.
  • mybranch..master, tham chiếu rõ ràng một trạng thái khác với cây làm việc hiện tại.
  • v2.0.1..master, tức là tham chiếu một thẻ.
  • [refspec]..[refspec], về cơ bản bất cứ điều gì có thể xác định là trạng thái mã để git.

33

Có nhiều cách để so sánh các tệp từ hai nhánh khác nhau:

  • Tùy chọn 1: Nếu bạn muốn so sánh tệp từ n nhánh cụ thể với một nhánh cụ thể khác:

    git diff branch1name branch2name path/to/file
    

    Thí dụ:

    git diff mybranch/myfile.cs mysecondbranch/myfile.cs
    

    Trong ví dụ này, bạn đang so sánh tập tin trong nhánh nhánh mybranchiến với tập tin trong nhánh của mys mysbrbranch.

  • Cách 2: Cách đơn giản:

     git diff branch1:file branch2:file
    

    Thí dụ:

     git diff mybranch:myfile.cs mysecondbranch:myfile.cs
    

    Ví dụ này tương tự như tùy chọn 1.

  • Tùy chọn 3: Nếu bạn muốn so sánh thư mục làm việc hiện tại của mình với một số chi nhánh:

    git diff ..someBranch path/to/file
    

    Thí dụ:

    git diff ..master myfile.cs
    

    Trong ví dụ này, bạn đang so sánh tệp từ nhánh thực tế của mình với tệp trong nhánh chính.


12

Tôi chỉ đơn giản là làm git diff branch1 branch2 path/to/file

Điều này kiểm tra sự khác biệt giữa các tập tin. Thay đổi trong branch1sẽ có màu đỏ. Thay đổi trong branch2sẽ có màu xanh lá cây.

Nó cho rằng đó branch1là quá khứ và branch2là tương lai. Bạn có thể đảo ngược điều này bằng cách đảo ngược thứ tự của các nhánh trong diff:git diff branch2 branch1


Phiên bản nào của git diff có thể làm điều này? Nó dường như không được hỗ trợ trong phiên bản tôi đang chạy (2..9.2.windows.1).
Vince Bowdren

9

Nếu bạn muốn tạo khác biệt so với chi nhánh hiện tại, bạn có thể sử dụng nó và sử dụng:

git diff $BRANCH -- path/to/file

bằng cách này, nó sẽ khác với nhánh hiện tại đến nhánh được tham chiếu ( $BRANCH).


5

Đồng ý với câu trả lời được đề xuất bởi @dahlbyk. Nếu bạn muốn diff được ghi vào tệp diff để đánh giá mã, hãy sử dụng lệnh sau.

git diff branch master -- filepath/filename.extension > filename.diff --cached

2

Trong trường hợp của tôi, tôi sử dụng lệnh dưới đây:

git diff <branch name> -- <path + file name>

Lệnh này có thể giúp bạn so sánh cùng một tệp trong hai nhánh khác nhau


1

Cách tốt nhất để làm điều đó là sử dụng git difftheo cách sau: git diff <source_branch> <target_branch> -- file_path

Nó sẽ kiểm tra sự khác biệt giữa các tập tin trong các chi nhánh. Hãy xem bài viết này để biết thêm thông tin về các lệnh git và cách chúng hoạt động.


1

Sử dụng băm cam kết như sau:

git diff <hash1> <hash2> <filename>

trong đó hash1 có thể là bất kỳ cam kết nào từ bất kỳ nhánh nào, giống nhau cho hash2 .


1

Có hai kịch bản để so sánh các tệp:

Kịch bản 1: So sánh các tệp tại các nhánh từ xa (cả hai nhánh nên tồn tại trên kho lưu trữ từ xa)

Kịch bản 2: So sánh các tệp cục bộ (tại bản sao vùng làm việc cục bộ) với các tệp tại kho lưu trữ từ xa.

Logic rất đơn giản. Nếu bạn cung cấp hai tên nhánh cho diff, nó sẽ luôn so sánh các nhánh từ xa và nếu bạn chỉ cung cấp một tên nhánh, nó sẽ luôn so sánh bản sao làm việc cục bộ của bạn với repo từ xa (tên bạn đã cung cấp). Bạn có thể sử dụng phạm vi để cung cấp kho từ xa.

ví dụ: Thanh toán chi nhánh

git checkout branch1
git diff branch2 [filename]

trong trường hợp này, nếu bạn cung cấp tên tệp, nó sẽ so sánh bản sao tên tệp cục bộ của bạn với nhánh từ xa có tên là " Branch2 ".

git diff branch1 branch2 [filename]

trong trường hợp này, nó sẽ so sánh tên tệp từ các nhánh từ xa có tên là " Branch1 " so với " Branch2 "

git diff ..branch2 [filename]

trong trường hợp này cũng vậy, nó sẽ so sánh tên tệp từ các nhánh từ xa có tên " Branch1 " so với " Branch2 ". Vì vậy, nó giống như trên. Tuy nhiên, nếu bạn vừa tạo một nhánh từ một nhánh khác, giả sử "master" và nhánh hiện tại của bạn không tồn tại trên kho lưu trữ từ xa, nó sẽ so sánh " master " từ xa với " Branch2 " từ xa .

Hy vọng nó hữu ích.


0

Để so sánh hai tệp trong git bash, bạn cần sử dụng lệnh:

git diff <Branch name>..master -- Filename.extension   

Lệnh này sẽ hiển thị sự khác biệt giữa hai tệp trong chính bash.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.