Nhận tất cả các tệp đã được sửa đổi trong nhánh git


208

Có cách nào để xem tập tin nào đã thay đổi trong một nhánh không?



2
Họ không phải là nhân viên của tôi, họ là đồng nghiệp của tôi và không phải họ nói riêng nhiều như mọi người nói chung. Nhưng phải, đọc lại bài này có vẻ hơi nông. :)
Raif

3
Bạn có thể sử dụng github hoặc bitbucket, gitlab? Có các công cụ để quản lý chính xác tình huống này. Các nhà phát triển thực hiện một yêu cầu kéo. Bạn nhận được yêu cầu và bạn sẽ có quyền truy cập vào một giao diện rất tốt sẽ hiển thị cho bạn một khác biệt của tất cả các thay đổi được thực hiện cho mỗi tệp. Bạn thậm chí có thể nhận xét, yêu cầu thay đổi, vv Khi các thay đổi tốt, bạn có thể chấp nhận yêu cầu sẽ hợp nhất các thay đổi vào nhánh được yêu cầu (thường phát triển). Đó là cách thực hành tốt nhất để xử lý tình huống này.
Scott Wright

Câu trả lời:


166

Một thay thế cho câu trả lời của @Marco Ponti và tránh việc thanh toán:

git diff --name-only <notMainDev> $(git merge-base <notMainDev> <mainDev>)

Nếu hệ vỏ cụ thể của bạn không hiểu cấu trúc $ (), thay vào đó hãy sử dụng dấu kiểm ngược.


1
Ah! điều này thật thú vị, bây giờ thì sao nếu tôi muốn nói <notMainDev> là chi nhánh hiện tại tôi đang ở. đó không phải là chỉ định nó?
Raif

29
git diff --name-only <some-other-branch>sẽ cho bạn thấy những tập tin nào khác nhau giữa chi nhánh hiện tại của bạn và <some-other-branch>. Vì vậy, nó chủ yếu lệnh giống nhau, nhưng lưu ý rằng bạn có thể sử dụng để tìm các tập tin khác nhau giữa bất kỳ hai chi nhánh, thậm chí nếu họ không liên quan từ xa. Việc so sánh đó có hữu ích hay không phụ thuộc vào cấu trúc liên kết của các nhánh của bạn ... Ngoài ra, lưu ý <some-other-branch>thực sự có thể là bất kỳ cam kết nào, hoặc bất cứ điều gì giải quyết thành một (thẻ, v.v.).
twalberg

hmmm, tôi đoán điều tôi muốn nói là tôi muốn thực hiện git diff - name-only <notMainDev> $ (git merge-base <notMainDev> <MY_CURRENT_CO_BRANCH>) trong đó MY_CURRENT_CO_BRANCH sẽ là chi nhánh hiện tại của tôi.
Raif

Bạn có thể làm điều đó, là tốt. Điều đó sẽ tìm ra điểm mà <notMainDev><MY_CURRENT_CO_BRANCH>gần đây nhất đã có một tổ tiên chung, và so sánh <notMainDev>với tổ tiên đó. Tuy nhiên, bạn sẽ phải cung cấp tên chi nhánh hiện tại của mình, như git merge-basemong đợi hai đối số - không có phím tắt, ít nhất là trong phiên bản hiện tại.
twalberg

1
đồng ý! Tôi hiểu rồi. Phép lịch sự của đồng nghiệp của tôi tên của anh ấy. git merge-base <notMainDev> git branch | grep '\*' | awk '{print $2}' sẽ nhận được cam kết cho nhánh giữa <notMainDev> và nhánh hiện tại của tôi. Sau đó tôi có thể thực hiện git diff --name-only <notMainDev> $ (git merge-base <notMainDev> git branch | grep '\*' | awk '{print $2}')
Raif

147

Tất cả bạn phải làm là như sau:

git checkout <notMainDev>
git diff --name-only <mainDev>

Điều này sẽ chỉ cho bạn các tên tệp khác nhau giữa hai nhánh.


wow nhanh chóng và quá quan điểm. cảm ơn bạn. btw tôi yêu git. nó luôn luôn nhanh chóng và đến điểm
Raif

23
Tuy nhiên, tôi tin rằng điều đó cũng sẽ hiển thị những thứ đã thay đổi <mainDev>kể từ khi các nhánh chuyển hướng. Bạn có thể muốn sử dụng git diff --name-only <sha-of-branch-point>thay thế hoặc xem câu trả lời thay thế mà tôi đã đăng để tránh việc thanh toán.
twalberg

Vâng, đó là sự thật @twalberg, nó sẽ hiển thị những thay đổi đó nếu các nhánh được chuyển hướng. Tôi đã giả định rằng notMainDevsẽ được cập nhật với các cam kết mainDev ... Tôi thường thấy cũng hữu ích khi thấy những khác biệt đó.
Marco Ponti

bạn không thể chỉ định - chỉ để hiển thị các tệp đã được thay đổi ở bên phải?
TheZenker

bạn nhận được <sha-of-branch-point>vớigit rev-parse <branch-name>
fc9.30

69

ngạc nhiên điều này đã không được nói cho đến nay!

git diff master...branch

Vì vậy, hãy xem những thay đổi chỉ trên branch

Để kiểm tra việc sử dụng chi nhánh hiện tại

git diff master...

Cảm ơn jqr

Đây là tay ngắn cho

git diff $(git merge-base master branch) branch

vì vậy cơ sở hợp nhất (cam kết phổ biến gần đây nhất giữa các nhánh) và đầu nhánh

Ngoài ra, sử dụng nguồn gốc / chủ thay vì chỉ chủ sẽ giúp ích trong trường hợp chủ địa phương của bạn bị lỗi thời


4
Mặc dù điều này cho thấy những gì đã thay đổi, nhưng nó hiển thị TẤT CẢ các thay đổi, thay vì tóm tắt các tệp đã thay đổi ... đó là điều dẫn tôi đến trang này ngay từ đầu :)
Chris Rutledge

1
sau đó thêm cờ --name-only vào đây. hoặc --short-stat
exussum

2
git diff --name-only master..nếu bạn chỉ muốn tên của các tệp khác nhau giữa hai nhánh.
Adam

1
Điều này sẽ không hoạt động đúng nếu chủ của bạn đã cam kết sau khi bạn tạo chi nhánh phụ của mình.
Simplylizz

2
@simplylizz đúng vậy. đó chính xác là những gì nó đang giải quyết
exussum

45

Tôi không thể tin rằng có rất nhiều cách để làm điều này. Tôi sử dụng whatchanged như ai đó đã đăng trước đó, chỉ với các đối số sau:

git whatchanged --name-only --pretty="" origin..HEAD

Điều này chỉ liệt kê tên tệp và chỉ những cái đã thay đổi trên nhánh hiện tại.


3
Đây dường như là câu trả lời dễ nhất ở đây vì nó không yêu cầu thêm thông tin. Đầu ra có vẻ chính xác và nó dễ nhớ hơn câu trả lời được chấp nhận!
RickMeasham

1
Cảm ơn, điều này là thú vị, nhiều từ. Nó cung cấp đầu ra fro mỗi cam kết, theo thứ tự ngược lại. git-whatchanged - Hiển thị nhật ký với sự khác biệt mỗi cam kết giới thiệu git-scm.com/docs/git-whatchanged
nealmcb

Từ các tài liệu git :New users are encouraged to use git-log instead. The whatchanged command is essentially the same as git-log but defaults to show the raw format diff output and to skip merges.
Derek S

21

Tôi thực sự thích câu trả lời của @ twalberg nhưng tôi không muốn phải gõ tên chi nhánh hiện tại mọi lúc. Vì vậy, tôi đang sử dụng điều này:

git diff --name-only $(git merge-base master HEAD)

1
Giải pháp của bạn làm việc cho tôi và tôi nhận được danh sách các tệp mà tôi muốn xem. Tôi là người mới chơi Git và đã sử dụng git diff master... --name-onlykhi chạy trên nhánh mục tiêu và nhận được kết quả tương tự. Bạn có thể tử tế khi cung cấp bất kỳ phản hồi nào về những gì tốt và xấu giữa câu trả lời của bạn và lệnh tôi đã cung cấp không?
hungerstar

Lệnh của bạn sẽ hoạt động chính xác như nhau, nếu chủ không có bất kỳ cam kết mới nào kể từ khi chi nhánh của bạn được tạo. Tôi nghĩ rằng lệnh của tôi sẽ tương đương với git diff master.. --name-only(lưu ý chỉ có 2 dấu chấm thay vì 3). Để hiểu ý nghĩa của các dấu chấm, hãy xem câu trả lời này
Yep_It's_Me

Tuyệt vời! Cảm ơn đã trả lời nhanh chóng và cái nhìn sâu sắc. Nhiều đánh giá cao.
hungerstar

12

git whatchanged dường như là một lựa chọn tốt


1
Chính xác là những gì tôi đang tìm kiếm.
Sild

Từ các tài liệu git :New users are encouraged to use git-log instead. The whatchanged command is essentially the same as git-log but defaults to show the raw format diff output and to skip merges.
Derek S

9
git diff --name-only master...branch-name

mà chúng tôi muốn so sánh.


Có vẻ như là một phần của câu trả lời hiện có, stackoverflow.com/a/41486181/11912
James Skemp

Biến thể này so sánh đầu của chủ với một nhánh hiện tại. Câu trả lời được chấp nhận so sánh trạng thái của chủ tại điểm bạn rẽ . Hoặc có thể có câu trả lời bạn đang tìm kiếm, tùy thuộc vào những gì bạn muốn biết.
Mark Stosberg

8

Điều gì nếu nó có thể dễ dàng như thế này?

git changed

Nếu bạn sẵn sàng cho rằng nhánh chính được gọi là "master" và bạn tạo các nhánh khác từ master, thì bạn có thể thêm bí danh này vào ~/.gitconfigtệp của mình để làm cho nó dễ dàng:

cbranch = !"git branch | grep '*' | cut -f2 -d' '"
changed = !"git diff --name-only $(git cbranch) $(git merge-base $(git cbranch) master)"

Những giả định đó sẽ có hiệu quả với hầu hết mọi người trong hầu hết các tình huống, nhưng bạn phải nhận thức được rằng bạn đang thực hiện chúng.

Ngoài ra, bạn phải sử dụng một vỏ hỗ trợ $(). Rất có khả năng vỏ của bạn hỗ trợ điều này .


3
git show --stat origin/branch_name

Điều này sẽ cung cấp cho bạn một danh sách các tập tin đã được thêm hoặc sửa đổi theo nhánh này.


2
Điều này là sai, điều này chỉ hiển thị các tệp được thay đổi trong cam kết đầu của chi nhánh đó, không phải toàn bộ chi nhánh.
davidtbernal

2

Vì một số lý do không ai nhắc đến git-tree. Xem https://stackoverflow.com/a/424142/1657819

git-treeđược ưa thích vì đó là lệnh hệ thống ống nước ; có nghĩa là lập trình (và, có lẽ, nhanh hơn)

(giả sử chi nhánh cơ sở là master)

git diff-tree --no-commit-id --name-only -r master..branch-name

Tuy nhiên, điều này sẽ hiển thị cho bạn tất cả các tệp bị ảnh hưởng trong nhánh, nếu bạn chỉ muốn xem các tệp được sửa đổi rõ ràng , bạn có thể sử dụng --diff-filter:

git diff-tree --no-commit-id --name-only -r master..branch-name --diff-filter=M

Ngoài ra, người ta có thể sử dụng --name-statusthay vì --name-onlyđể xem trạng thái của các tệp ( A/ M/ Dv.v.)


Đây chỉ là những gì tôi cần để thay đổi các tập tin đã thay đổi trong khi loại trừ những tập tin đã bị xóa. rubocop --fail-level error $(git diff-tree --no-commit-id --name-only -r origin/master..HEAD --diff-filter=M)
HarlemSquirrel

1

Câu trả lời được chấp nhận - git diff --name-only <notMainDev> $(git merge-base <notMainDev> <mainDev>)- rất gần, nhưng tôi nhận thấy rằng nó có tình trạng sai khi xóa. Tôi đã thêm một tệp trong một nhánh và lệnh này (bằng cách sử dụng --name-status) đã cho tệp tôi đã xóa trạng thái "A" và tệp tôi đã thêm trạng thái "D".

Tôi đã phải sử dụng lệnh này thay thế:

git diff --name-only $(git merge-base <notMainDev> <mainDev>)

0

Mở rộng ra những gì @twalberg và @iconoclast đã có, nếu bạn đang sử dụng cmd vì bất kỳ lý do gì, bạn có thể sử dụng:

FOR /F "usebackq" %x IN (`"git branch | grep '*' | cut -f2 -d' '"`) DO FOR /F "usebackq" %y IN (`"git merge-base %x master"`) DO git diff --name-only %x %y

0

Tệp bó sau dựa trên câu trả lời của twalberg nhưng sẽ hoạt động trong Windows:

@ECHO OFF
C:                               :: <== OR USE A DIFFERENT DRIVE
CD \path\to\where\git\files\are  :: <== CHANGE TO THE ACTUAL PATH
SET /p b="Enter full path of an ALREADY MERGED branch to compare with origin/master: "
bash --login -i -c "git diff --name-only %b% $(git merge-base %b1% origin/drop2/master)"
PAUSE

Giả định ở trên giả định rằng nhánh chính là origin / master và git bash được bao gồm khi Git được cài đặt (và vị trí của nó nằm trong môi trường đường dẫn). Tôi thực sự cần phải hiển thị sự khác biệt thực tế bằng cách sử dụng một công cụ tìm khác biệt được cấu hình (kdiff3) để thay thế lệnh bash sau ở trên:

bash --login -i -c "git difftool --dir-diff %b% $(git merge-base %b1% origin/drop2/master)"

0

Tôi sử dụng grep vì vậy tôi chỉ nhận được các dòng với diff --git là đường dẫn tệp:

git diff branchA branchB | grep 'diff --git'
// OUTPUTS ALL FILES WITH CHANGES, SIMPLE HA :)
diff --git a/package-lock.json b/package-lock.json
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.