2013-08-18 23 views
7

Tôi đang cố gắng để thúc đẩy một số mã sử dụng $git push origin master nhưng tôi nhận được lỗiLàm cách nào để biết những tệp nào trên kho lưu trữ từ xa đã thay đổi kể từ lần kéo git cuối cùng?

! [rejected]  master -> master (non-fast-forward) 
error: failed to push some refs to 'https://github.com/' 
To prevent you from losing history, non-fast-forward updates were rejected 
Merge the remote changes (e.g. 'git pull') before pushing again. See the 
'Note about fast-forwards' section of 'git push --help' for details. 

Khi tôi đã làm $ git fetch origin master sau đó $ git diff master origin/master tôi nhận được một danh sách tất cả các tập tin và thay đổi mà là khác nhau giữa hai Repos. Tuy nhiên, tôi chỉ quan tâm đến danh sách các tệp đã thay đổi giữa kho lưu trữ từ xa và lần cuối cùng tôi thực hiện một số $ git pull origin master trên hộp địa phương của mình.

Có cách nào tôi có thể thực hiện việc này không?

Trả lời

2
git diff --stat master origin/master 
+0

Điều này thực sự so sánh cam kết hiện tại của bạn ('master') với giá trị của chúng (' origin/master'), không phải là * khá * giống nhau. – torek

6

git pull cũng giống như git fetch Tiếp theo git merge (hoặc git rebase).

git fetch hiển thị quảng cáo nào được cập nhật. Nó sẽ hiển thị một cái gì đó như:

a8e5e4e..295bf31 master  -> origin/master 

Đây có nghĩa là lần cuối cùng bạn tìm kiếm chính tại thời điểm hiện tại là 295bf31. Bạn có thể xem các tập tin đã thay đổi với một cái gì đó như:

git diff --name-status a8e5e4e..295bf31 

Nhưng có lẽ thậm chí thú vị hơn là sản phẩm của gitk master...origin/master sau khi lấy. Bằng cách này, bạn có thể kiểm tra cả những thay đổi trên mặt của bạn và những thay đổi ở bên xuất xứ.

+0

Tôi thấy rằng với --name-status Tôi cũng cần - chỉ-tên để chỉ hiển thị tên tập tin chứ không phải sự khác biệt. – bgoodr

4

michas' answer là câu hỏi phù hợp cho câu hỏi được hỏi.

Điều gì xảy ra nếu bạn không có ref cũ, tức là phần a8e5e4e của a8e5e4e..295bf31 master -> origin/master? Có lẽ bạn không thực sự quan tâm: như ông đề nghị, nhìn vào master...origin/master thậm chí có thể thú vị hơn. Nhưng cú pháp ba chấm ... này thực sự là gì có nghĩa là?

Câu trả lời là trong tài liệu git rev-list:

Một ký hiệu đặc biệt là <commit1>...<commit2> đó là hữu ích cho sáp nhập. Tập hợp các cam kết là sự khác biệt đối xứng giữa hai toán hạng. ...

mà tôi nghi ngờ là từ ngữ đủ khó hiểu (và thực sự là git diff sử dụng một ý nghĩa hoàn toàn khác). Nhưng thực sự, nó không phải là phức tạp.

Với một số cam kết có thể được rút ra như thế này:

master origin/master 

    E  G 
    |  | 
    D  F 
    \ /
     C 
     | 
     B 
     | 
     A 

những gì bạn có là một phân kỳ tại cam C. Bạn bắt đầu làm việc khi masterorigin/master cả hai đều trỏ đến C. Rõ ràng, bạn cam kết DE và "họ" (dù họ là ai) cam kết FG. Cam kết C, nhân tiện, được gọi là cơ sở hợp nhất .

Điều gì master...origin/master có nghĩa là: tìm tôi C và sau đó cung cấp cho tôi mọi thứ "từ đó", ở cả hai bên trái và bên phải. Tức là, tất cả các cam kết trên cả hai số masterorigin/master, ngoại trừ mọi cam kết tại-và-dưới điểm mà chúng gặp nhau lần đầu tiên.

Nếu bạn chạy gitk master...origin/master bạn sẽ thấy điều đó: tất cả các cam kết bạn thực hiện, và tất cả các cam kết họ thực hiện. Tuy nhiên, nếu bạn chạy git diff flags master...origin/master, git diff sẽ ném hầu hết điều này. Thay vào đó, nó tìm thấy cơ sở hợp nhất C, và khác với tên bên phải.

Giả sử bạn đang ở trên chi nhánh master (tức là, HEAD chỉ có nghĩa là "chính"), bạn có thể rút ngắn điều này hơn nữa. Để xem những tập tin họ thay đổi kể từ bạn và các chi nhánh của họ tách ra, chỉ cần chạy:

$ git diff --stat ...origin/master # or --name-status, etc 

Rời tên ra khỏi nghĩa HEAD, vì vậy đây là giống như HEAD...origin/master mà là giống như master...origin/master.

Nếu git của bạn là đủ mới, @{u} đề cập đến "chi nhánh thượng nguồn các chi nhánh hiện tại của" (ví dụ, từ master, tìm origin/master), do đó bạn có thể chạy:

$ git diff --stat '[email protected]{u}' 

(có dấu ngoặc kép là để bảo vệ sự niềng răng từ vỏ, chúng có thể hoặc có thể không cần thiết trong vỏ của bạn). Này hoạt động ngay cả khi bạn đang ở trên develop với origin/develop như thượng nguồn của nó, hoặc featureX với origin/featureX như thượng nguồn của nó, vv


Nếu bạn không có gitk, hãy thử:

$ git log --graph --boundary ...origin/master 

(hoặc '[email protected]{u}' như đã nêu ở trên). Bạn cần --boundary để bao gồm cam kết hợp nhất. Bạn cũng có thể muốn thêm --oneline --decorate.

Trên thực tế gitk sẽ cho bạn thấy việc hợp nhất cam kết quá, giống như các lệnh trong chú thích 1. Đó là, nó sử dụng --boundary bao gồm đáp ứng điểm cam kết (đây là không hoàn toàn giống như các căn cứ hợp nhất, nhưng gần đủ).

Giả định này có chính xác một cam kết hợp nhất cơ sở. Đối với những trường hợp này, điều đó đúng. Vì vậy, git diff so sánh cây cho C với cây cho G ở phần đầu của nhánh thượng nguồn. Bạn sẽ so sánh "nơi họ đã" với "nơi họ đã kết thúc", bất kể bất kỳ điểm trung gian nào họ truy cập có lẽ là một ổ đĩa dài tùy ý. :-) Ví dụ, nếu cam kết F thêm một tập tin this/that và sau đó cam kết G loại bỏ nó một lần nữa, bạn sẽ không thấy tệp.

Các vấn đề liên quan