Làm cách nào để tạo một git diff của những gì đã thay đổi kể từ lần cuối cùng tôi kéo?


77

Tôi muốn viết kịch bản, tốt nhất là trong rake, các hành động sau thành một lệnh duy nhất:

  1. Tải phiên bản của kho lưu trữ git cục bộ của tôi.
  2. Git kéo mã mới nhất.
  3. Git khác với phiên bản tôi đã trích xuất ở bước # 1 với phiên bản hiện có trong kho lưu trữ cục bộ của tôi.

Nói cách khác, tôi muốn lấy mẫu mã mới nhất từ ​​kho lưu trữ trung tâm và ngay lập tức tạo ra sự khác biệt về những gì đã thay đổi kể từ lần cuối cùng tôi kéo.

Câu trả lời:


92

Bạn có thể làm điều này khá đơn giản với refspec.

git pull origin
git diff @{1}..

Điều đó sẽ cung cấp cho bạn sự khác biệt của nhánh hiện tại như nó tồn tại trước và sau khi kéo. Lưu ý rằng nếu pull không thực sự cập nhật nhánh hiện tại, thì diff sẽ cho bạn kết quả sai. Một tùy chọn khác là ghi lại phiên bản hiện tại một cách rõ ràng:

current=`git rev-parse HEAD`
git pull origin
git diff $current..

Cá nhân tôi sử dụng một bí danh chỉ đơn giản là hiển thị cho tôi một nhật ký, theo thứ tự ngược lại (tức là cũ nhất đến mới nhất), không hợp nhất, của tất cả các cam kết kể từ lần kéo cuối cùng của tôi. Tôi chạy điều này mỗi khi kéo của tôi cập nhật nhánh:

git config --global alias.lcrev 'log --reverse --no-merges --stat @{1}..

1
@leemes: Hmm? git diff HEADsẽ cho bạn thấy những gì đã thay đổi giữa HEAD và bản sao làm việc hiện tại của bạn. Đó không phải là những gì Teflon Ted đang yêu cầu.
Lily Ballard

Xin lỗi, tôi đã hiểu sai câu hỏi. Tôi đang tìm kiếm một lệnh để hiển thị các thay đổi của mình kể từ lần cuối cùng tôi kéo và hạ cánh ở đây. git diff HEADđã làm việc cho những gì tôi cần (ít nhất tôi đoán rằng đó là những gì tôi đang tìm kiếm: D)
leemes

4
Ai đó có thể giải thích (hoặc cho tôi biết nơi đọc tiếp) những gì @{1}..chính xác đo lường? Chỉ ném nó vào Google không giúp ích gì.
user1129682 14/12/12

5
@ user1129682: Đó là cú pháp để truy cập vào reflog . Nếu không có tên chi nhánh, nó có nghĩa là truy cập vào bản ghi lại của chi nhánh hiện tại. Giá trị của @{1}nghĩa là mục nhập nhật ký gần đây nhất, ví dụ như bất cứ điều gì mà nhánh hiện tại trỏ đến trước khi nó trỏ đến cam kết hiện tại.
Lily Ballard

2
+1, đây là cách chính xác. Bạn nên mở rộng một chút về @{1}..ký hiệu, có thể đặt các giá trị mặc định ở đó một cách rõ ràng và sau đó hiển thị phiên bản nhỏ gọn, như vậy sẽ bớt ảo diệu hơn.
slzica

12

Cách của Greg sẽ hiệu quả (không phải tôi, Greg khác: P). Về nhận xét của bạn, origin là một biến cấu hình được Git đặt khi bạn sao chép kho lưu trữ trung tâm vào máy cục bộ của mình. Về cơ bản, kho lưu trữ Git ghi nhớ nó đến từ đâu. Tuy nhiên, bạn có thể đặt các biến này theo cách thủ công nếu bạn cần sử dụng git-config.

git config remote.origin.url <url>

trong đó url là đường dẫn từ xa đến kho lưu trữ trung tâm của bạn.

Đây là một tệp hàng loạt ví dụ sẽ hoạt động (tôi chưa thử nghiệm nó).

@ECHO off

:: Retrieve the changes, but don't merge them.
git fetch

:: Look at the new changes
git diff ...origin

:: Ask if you want to merge the new changes into HEAD
set /p PULL=Do you wish to pull the changes? (Y/N)
IF /I %PULL%==Y git pull

1
Thông thường, bạn sẽ sử dụng git remote set-url origin <url>thay vì thay git configđổi URL cho điều khiển từ xa Git . Có sự khác biệt? Tôi không biết, nhưng có vẻ như đó git remotelà một công cụ thích hợp hơn cho công việc.
Colin D Bennett

@ColinDBennett Bạn nói đúng, git remote set-urlsẽ là cách thích hợp hơn để làm điều đó. Tôi đã sử dụng git configset-urlkhông phải là một lựa chọn khi tôi viết cái này ban đầu.
Greg

10

Điều này rất giống với một câu hỏi tôi đã hỏi về cách nhận các thay đổi trên một nhánh trong git . Lưu ý rằng hoạt động của git diff so với git log là khác nhau hoàn toàn khi sử dụng hai dấu chấm so với ba dấu chấm. Tuy nhiên, đối với ứng dụng của bạn, bạn có thể sử dụng:

git fetch
git diff ...origin

Sau đó, a git pullsẽ hợp nhất các thay đổi vào HEAD của bạn.


Tôi không thấy nguồn gốc được định nghĩa là một từ khóa đặc biệt cho git-diff hoặc git-rev-parse. Ý của bạn là tôi cần phải nhập hàm băm từ bước # 1 làm giá trị cho điểm gốc? Nếu vậy, làm cách nào để trích xuất giá trị đó theo chương trình? Tôi muốn kết hợp tất cả các bước này thành một lệnh / tập lệnh duy nhất để thuận tiện.
Teflon Ted

2
Một cách khác để thực hiện việc này là sử dụng phần đầu FETCH_HEAD đặc biệt, phần đầu này phản ánh kết quả của lần tìm nạp trước đó. Vì vậy: "git fetch && git diff ... FETCH_HEAD".
Greg Hewgill 14/09/08

Tôi nghĩ đây là câu trả lời thích hợp hơn: git fetchtheo sau là a git diff origin/branchnamelà cách tốt nhất để kiểm tra sự khác biệt trước khi kéo.
Giulio Caccin

4

Nếu bạn thả nó vào hồ sơ bash của mình, bạn sẽ có thể chạy nụ cười (git từ xa đến) và grout (git từ xa gửi đi) để xem sự khác biệt của các cam kết đến và đi cho bản gốc.

function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}
function gd2 { 
 echo branch \($1\) has these commits and \($2\) does not 
 git log $2..$1 --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local
}
function grin {
 git fetch origin master
 gd2 FETCH_HEAD $(parse_git_branch)
}
function grout {
 git fetch origin master
 gd2 $(parse_git_branch) FETCH_HEAD
}

Gd2 là gì? Một số loại bí danh để git diff?
cung cấp

Đó là một chức năng bash được xác định trong kịch bản trên ngay sau khi parse_git_branch
Clintm
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.