Báo cáo hợp nhất Git đã được cập nhật, mặc dù có sự khác biệt


286

Tôi có một kho git với 2 nhánh: master và test.

Có sự khác biệt giữa các nhánh chính và thử nghiệm.

Cả hai chi nhánh đều có những thay đổi đã cam kết.

Nếu tôi làm:

chủ thanh toán git
kiểm tra khác biệt git

Một màn hình đầy những thay đổi xuất hiện cho thấy sự khác biệt. Tôi muốn hợp nhất các thay đổi trong nhánh thử nghiệm và cũng vậy:

kiểm tra hợp nhất git

Nhưng nhận được thông báo "Đã cập nhật"

Tuy nhiên, kiểm tra các tệp theo từng nhánh khác nhau cho thấy rõ sự khác biệt.

Vấn đề ở đây là gì và làm thế nào để tôi giải quyết nó?


Bạn có mã sửa đổi không cam kết?
ozma

Câu trả lời:


146

Thông báo có sẵn Cập nhật có nghĩa là tất cả các thay đổi từ chi nhánh bạn đang cố gắng hợp nhất đã được hợp nhất với chi nhánh bạn hiện đang thực hiện. Cụ thể hơn, điều đó có nghĩa là chi nhánh bạn đang cố gắng hợp nhất là cha mẹ của chi nhánh hiện tại của bạn . Xin chúc mừng, đó là sự hợp nhất dễ dàng nhất mà bạn từng làm. :)

Sử dụng gitkđể xem kho lưu trữ của bạn. Nhãn cho nhánh nhánh thử nghiệm của Wap nên ở đâu đó bên dưới nhãn nhánh nhánh của bạn.

Chi nhánh của bạn được cập nhật liên quan đến cha mẹ của nó. Theo hợp nhất, không có thay đổi mới trong cha mẹ kể từ lần hợp nhất cuối cùng. Điều đó không có nghĩa là các nhánh giống nhau, bởi vì bạn có thể có nhiều thay đổi trong nhánh làm việc của mình và nó có vẻ như bạn làm.

Chỉnh sửa 10/12/2019:

Theo Charles Drake trong bình luận cho câu trả lời này, một giải pháp để khắc phục vấn đề là:

git checkout master
git reset --hard test

Điều này đưa nó trở lại mức 'thử nghiệm'.

Sau đó làm:

git push --force origin master

để buộc thay đổi trở lại repo trung tâm.


2
Thánh cr * p! Bạn đúng! Tôi nghĩ những gì đã xảy ra là một nhánh khác (phát triển không ổn định) đã được hợp nhất không chính xác với chủ và nhánh thử nghiệm là một tập hợp con không ổn định. Sự hợp nhất mà tôi đang cố gắng thực hiện là đưa chủ nhân trở lại mức 'thử nghiệm'.
Charles Darke

2
Đúng. Hoạt động đó sẽ không có ý nghĩa gì nên Git từ chối làm bất cứ điều gì. :)
Bombe

24
Những gì tôi đã làm bây giờ là: git checkout master; git reset - kiểm tra độ trễ; Điều này đưa nó trở lại mức 'thử nghiệm'. Sau đó tôi đã thực hiện một "git đẩy - Force master master" để buộc thay đổi trở lại repo trung tâm.
Charles Darke

22
Sẽ thật tuyệt nếu git có một cảnh báo là "cố gắng hợp nhất với cha mẹ".
Charles Darke

1
Đẩy một nhánh không phải là hậu duệ của nhánh đã tồn tại ở phía xa được coi là một điều xấu: Xem các cuộc thảo luận trên các trang man để biết git-đẩy và git-pull.
Bombe

131

Điều này thường xảy ra với tôi khi tôi biết có những thay đổi trên chủ từ xa, vì vậy tôi cố gắng hợp nhất chúng bằng cách sử dụng git merge master. Tuy nhiên, điều này không hợp nhất với chủ từ xa, mà với chủ địa phương của bạn.

Vì vậy, trước khi thực hiện hợp nhất, kiểm tra tổng thể, và sau đó git pullở đó. Sau đó, bạn sẽ có thể hợp nhất các thay đổi mới vào chi nhánh của bạn.


7
Có cách nào để chuyển đổi các nhánh có thể tránh được, một cái gì đó giống như kéo một nhánh được sáp nhập trong khi vẫn ở nhánh được sáp nhập vào, và sau đó hợp nhất?
Japheth Ongeri - inkalimeva

Ahh, một trong những tốt đẹp. Tôi nghĩ rằng git fetchsẽ cập nhật nhánh chính ngay cả khi tôi hiện đang ở một nhánh khác. Hóa ra là không. Cảm ơn! Tôi khá chắc chắn rằng có một tùy chọn cho fetchphép bạn chỉ định chi nhánh nào sẽ nhận được.
Raik

1
@Raik Bạn có thể làm git fetch --all, nhưng điều này chỉ lấy các nhánh, nó không kéo chúng.
Ingo Bürk

6
@ JaphethOngeri-inkalimeva Bạn chỉ có thể làm git fetch --all && git merge origin/master. Không cần cập nhật cục bộ của bạn masterđể hợp nhất các thay đổi từ xa.
Ingo Bürk

@ IngoBürk Tôi có 2 chi nhánh, cập nhật 1 với git merge mastervà 1 với git merge origin/master. Tôi cũng đã kiểm tra mastergit pulltrước khi cập nhật 2 chi nhánh. mặc dù họ đã chia sẻ cùng một nội dung, việc tạo PR giữa 2 nhánh cho thấy một số tệp khác. Tôi đã sửa lỗi bởi git pullnhánh mục tiêu thành nhánh tính năng, điều này cho thấy: Already up to date! Merge made by the 'recursive' strategy.điều này dẫn đến cam kết hợp nhất không có thay đổi, nhưng đã loại bỏ các tệp khác biệt không mong muốn khỏi PR. bất cứ ý tưởng tại sao có sự khác biệt giữa việc hợp nhất các chi nhánh địa phương và từ xa "tương đương"?
giấy gói

45

Giả sử bạn có một chi nhánh mastervới lịch sử cam kết sau:

A -- B -- C -- D

Bây giờ, bạn tạo một bài kiểm tra chi nhánh, làm việc với nó và thực hiện 4 lần xác nhận:


                 E -- F -- G -- H
                /
A -- B -- C -- D

masterĐầu của nó chỉ vào D và testđầu của nó chỉ vào H.

Thông báo "Đã cập nhật" hiển thị khi TRỤ của chi nhánh bạn hợp nhất là cha mẹ của chuỗi cam kết của chi nhánh bạn muốn hợp nhất. Đó là trường hợp, ở đây: Dlà cha mẹ của E.

Không có gì để merge từ là testđể master, vì không có gì đã thay đổi trên mastertừ đó. Những gì bạn muốn làm ở đây theo nghĩa đen là bảo Git phải có masterđầu để chỉ vào H, vì vậy chi nhánh của chủ nhân có lịch sử cam kết sau:

A -- B -- C -- D -- E -- F -- G -- H

Đây là một công việc cho lệnh Git reset. Bạn cũng muốn thư mục làm việc phản ánh sự thay đổi này, vì vậy bạn sẽ thực hiện thiết lập lại cứng :

git reset --hard H

3
Trước đây tôi đã nói rằng việc sử dụng git reset --hardlà một việc khá quyết liệt để làm, liệu nó có thể bị mất các cam kết không? Có cách nào an toàn hơn để thực hiện những thay đổi này, hoặc là những nguy hiểm của sự git reset --hardcường điệu hóa?
Graham R. Armstrong

1
Lệnh này là lành mạnh, không phải lo lắng. Tôi muốn nói rằng điều duy nhất cần chú ý với --hardtùy chọn là nó thực sự sửa đổi thư mục làm việc của bạn và do đó, bạn mất các thay đổi không được cam kết. Cá nhân, tôi thực hiện git statustrước và sau mỗi lệnh git chạy thủ công để đảm bảo repo của tôi sạch hoặc ở trạng thái mong đợi.
Marek Stanley

điều này sẽ tạo ra thông báo trạng thái "Chi nhánh và 'nguồn gốc / chủ' của bạn đã chuyển hướng", làm cách nào để giải quyết nó?
Eido95

1
Tôi ước tôi có thể cung cấp cho bạn nhiều hơn một upvote. Cảm ơn!
KMC

Có bất kỳ nhu cầu cho các --hardtùy chọn? Tôi đã ở trong tình huống này một vài lần và luôn luôn thiết lập lại mà không có --hard. Nó hoạt động tốt mà không có nguy cơ mất bất kỳ thay đổi không cam kết.
Casimir

16

Những gì làm việc cho tôi, giả sử bạn có nhánh1 và bạn muốn hợp nhất nó vào nhánh2.

Bạn mở dòng lệnh git đi đến thư mục gốc của nhánh2 và gõ:

git checkout branch1
git pull branch1
git checkout branch2
git merge branch1
git push

Nếu bạn có comflicts, bạn không cần phải thực hiện git đẩy, nhưng trước tiên hãy giải quyết các conflits và sau đó đẩy.


6

Hợp nhất luôn nằm giữa CHÍNH hiện tại và một hoặc nhiều cam kết (thường là đầu chi nhánh hoặc thẻ)
và tệp chỉ mục phải khớp với cây của cam kết CHÍNH (tức là nội dung của cam kết cuối cùng) khi bắt đầu.
Nói cách khác, git diff --cached HEADphải báo cáo không có thay đổi.

Các cam kết hợp nhất đã được chứa trong HEAD. Đây là trường hợp đơn giản nhất, được gọi là "Đã cập nhật."

Điều đó có nghĩa là các cam kết trong thử nghiệm đã được hợp nhất trong tổng thể, nhưng vì các cam kết khác được thực hiện trên chủ, git diff testnên vẫn có một số khác biệt.


6

Điều này xảy ra vì bản sao cục bộ của chi nhánh bạn muốn hợp nhất đã hết hạn. Tôi đã có chi nhánh của mình, được gọi MyBranchvà tôi muốn hợp nhất nó vào ProjectMaster.

_>git status
On branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

nothing to commit, working tree clean

_>git merge ProjectMaster
Already up-to-date.

Nhưng tôi biết rằng có những thay đổi cần phải được hợp nhất!

Đây là điều, khi tôi gõ git merge ProjectMaster, git nhìn vào bản sao cục bộ của chi nhánh này, có thể không phải là hiện tại . Để xem đây có phải là trường hợp không, trước tiên tôi nói với Git kiểm tra và xem nếu các chi nhánh của tôi đã hết hạn và tìm nạp bất kỳ thay đổi nào nếu sử dụng, uh fetch,. Sau đó, tôi nhảy vào chi nhánh mà tôi muốn hợp nhất để xem những gì đang xảy ra ở đó ...

_>git fetch origin

_>git checkout ProjectMaster
Switched to branch ProjectMaster
**Your branch is behind 'origin/ProjectMaster' by 85 commits, and can be fast-forwarded.**
  (use "git pull" to update your local branch)

À ha! Bản sao địa phương của tôi đã cũ bởi 85 cam kết, điều đó giải thích mọi thứ! Bây giờ, tôi Pullxuống các thay đổi tôi đang thiếu, sau đó nhảy qua MyBranchvà thử hợp nhất lại.

_>git pull
Updating 669f825..5b49912
Fast-forward

_>git checkout MyBranch-Issue2
Switched to branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

_>git merge ProjectMaster
Auto-merging Runbooks/File1.ps1
CONFLICT (content): Merge conflict in Runbooks/Runbooks/File1.ps1

Automatic merge failed; fix conflicts and then commit the result.

Và bây giờ tôi có một vấn đề khác cần khắc phục ...


5

Điều này xảy ra với tôi vì GIT kỳ lạ nghĩ rằng chi nhánh địa phương khác với chi nhánh từ xa. Điều này có thể nhìn thấy trong biểu đồ nhánh: nó hiển thị hai nhánh khác nhau: điều khiển từ xa / origin / Branch_name và Branch_name.

Giải pháp đơn giản là loại bỏ repo cục bộ và sao chép lại từ xa. Bằng cách này, GIT sẽ hiểu rằng điều khiển từ xa / origin / Branch_name> và Branch_name thực sự giống nhau và tôi có thể phát hành git merge branch_name.

rm <my_repo>
git clone <my_repo>
cd <my_repo>
git checkout <branch_name>
git pull
git checkout master
git merge <branch_name>

Đây không phải là câu trả lời chính xác như của Acarter sao?
Andrew C

Tôi nghĩ rằng Acarter thực sự đã bỏ lỡ vấn đề - không có bất kỳ thay đổi nào trên điều khiển từ xa - đó hoàn toàn không phải là vấn đề. Tôi cần phải "git checkout master" và sau đó "git merge <Branch_name>" để buộc hợp nhất chuyển tiếp nhanh. Cách khác là không làm gì cả vì chi nhánh đã đi trước chủ. Câu trả lời của Bombe là một lời giải thích hay nhưng không bao giờ trả lời phần "làm thế nào để tôi giải quyết nó" trong câu hỏi.
MrMas

5

git merge origin/masterthay vì git merge masterlàm việc cho tôi Vì vậy, để hợp nhất tổng thể vào nhánh tính năng, bạn có thể sử dụng:

git checkout feature_branch
git merge origin/master

5

Hãy chắc chắn kiểm tra chi nhánh bạn muốn hợp nhất trước rồi kéo nó (để phiên bản địa phương của bạn khớp với phiên bản từ xa).

Sau đó kiểm tra lại chi nhánh của bạn mà bạn muốn thực hiện hợp nhất và hợp nhất git của bạn sẽ hoạt động.


1
Đây là nó cho tôi - tôi đã làm một việc trong khi ở trong chủ; phải biết rằng tôi đã nhận được các cam kết mới trong "chi nhánh". Đã thử hợp nhất "chi nhánh" thành chủ - "Đã cập nhật". Đã kiểm tra git "chi nhánh" - có "Chi nhánh của bạn đứng sau ... và có thể được chuyển tiếp nhanh.", Điều đó có nghĩa là tôi cần cập nhật "chi nhánh" bằng cách chạy git pulltrong "chi nhánh"
sdbbs

3

chúc mừng tôi và được gửi đến trang này, không chắc tôi có kịch bản tương tự không, nhưng tôi là tôi đang cố gắng "hợp nhất lại" chi nhánh "thử nghiệm" đó.

Vì vậy, trước đây tôi đã hợp nhất nó nhưng tôi cố tình loại trừ một số thay đổi cụ thể trong quá trình hợp nhất đó, vì vậy nó rõ ràng có một số khác biệt giữa các nhánh. Sau đó, tôi đã cố gắng hợp nhất lại vì tôi nhận ra / quên rằng tôi nên có và muốn thêm một thay đổi / tệp cụ thể mà trước đây tôi đã loại trừ và tôi hy vọng nếu tôi thực hiện hợp nhất lại sẽ hiển thị tất cả các thay đổi mà tôi đã loại trừ trước đó , nhưng tôi đã sai và thay vào đó tôi nhận được thông báo "Đã cập nhật".

Khi đọc bình luận / câu trả lời của @ Bombe, anh ấy đã đúng, và tôi nghĩ rằng tôi hành xử theo cách đó, vì vậy, những gì tôi đã làm là sao lưu cứng các tệp trên nhánh thử nghiệm, sau đó kiểm tra nhánh chính và dán thủ công các tệp vào đó và cam kết như thể đó là những thay đổi mới.

không chắc đây là cách đúng hay có thể giúp những người khác gặp vấn đề tương tự, nhưng nó đã cung cấp giải pháp cho trường hợp cụ thể của tôi.


Tình hình tương tự ở đây. Kịch bản là tôi muốn tách một nhánh "tích hợp" lại thành nhiều nhánh "tính năng".
Yadli

2
Thay vì dán thủ công, bạn có thể kiểm tra các tệp trực tiếp từ một nhánh vào nhánh hiện tại : git checkout srcBranch -- path/to/file. Có thể sử dụng tập tin ảm đạm quá.
Todd

Cảm ơn, tôi đã sử dụng phương thức thanh toán của bạn, nhưng tôi đã đặt checkout srcBranch -- *và sau đó xem xét các khác biệt của mình
portforwardpodcast

2

Nếu sáp nhập chi nhánh A vào chi nhánh B báo cáo "Đã cập nhật", điều ngược lại không phải lúc nào cũng đúng. Điều này chỉ đúng nếu nhánh B là hậu duệ của nhánh A, nếu không, nhánh B đơn giản có thể có những thay đổi không thuộc A.

Thí dụ:

  1. Bạn tạo nhánh A và B tắt master
  2. Bạn thực hiện một số thay đổi trong bản gốc và chỉ hợp nhất những thay đổi này vào nhánh B (không cập nhật hoặc quên cập nhật nhánh A).
  3. Bạn thực hiện một số thay đổi trong nhánh A và hợp nhất A thành B.

Tại thời điểm này, việc hợp nhất A đến B báo cáo "Đã cập nhật" nhưng các nhánh khác nhau vì nhánh B có cập nhật từ chủ trong khi nhánh A thì không.


2

Đối mặt với kịch bản này bằng cách sử dụng Git Bash.

Kho lưu trữ của chúng tôi có nhiều chi nhánh và mỗi chi nhánh có một chu kỳ cam kết khác nhau và việc hợp nhất xảy ra một lần trong một thời gian. Old_Branch đã được sử dụng làm cha mẹ cho New_Branch

Old_Branch đã được cập nhật với một số thay đổi cần được hợp nhất với New_Branch

Đã sử dụng lệnh pull bên dưới mà không có bất kỳ nhánh nào để lấy tất cả các nguồn từ tất cả các nhánh.

nguồn gốc git kéo

Kỳ lạ là điều này không kéo tất cả các cam kết từ tất cả các chi nhánh. Đã nghĩ như vậy vì chỉ định cho thấy hầu hết tất cả các chi nhánh và thẻ.

Vì vậy, để khắc phục điều này đã kiểm tra Old_Branch đã kéo mới nhất bằng cách sử dụng

kiểm tra git Old_Branch

nguồn gốc git kéo Old_Branch

Bây giờ đã kiểm tra New_Branch

kiểm tra git New_Branch

Kéo nó để chắc chắn

nguồn gốc git kéo New_Branch

hợp nhất git Old_Branch

Và viola có xung đột để khắc phục từ Old_Branch sang New_Branch :) đã được mong đợi


0

Điều tương tự cũng xảy ra với tôi. Nhưng kịch bản hơi khác một chút, tôi có nhánh chính và tôi đã phát hành bản phát hành_1 (nói) ra khỏi nó. Thực hiện một số thay đổi trong nhánh phát hành_1 và hợp nhất nó vào nguồn gốc. sau đó tôi đã thực hiện ssh và trên máy chủ từ xa, tôi lại kiểm tra phát hành_1 bằng cách sử dụng lệnh git checkout -b release_1 - thực sự tạo ra một bản phát hành chi nhánh mới_! từ chủ thay vì kiểm tra bản phát hành chi nhánh hiện có_1 từ nguồn gốc. Đã giải quyết vấn đề bằng cách xóa công tắc "-b"


0

Tôi đã từng gặp vấn đề tương tự. Tôi đã có những thay đổi trong điều khiển từ xa và nó vẫn hiển thị "Đã cập nhật". Recloning các kho lưu trữ đã khắc phục vấn đề cho tôi.


0

Ngớ ngẩn nhưng nó có thể xảy ra. Giả sử tên chi nhánh của bạn được thêm tiền tố với một tham chiếu vấn đề (ví dụ #91-fix-html-markup), nếu bạn thực hiện việc hợp nhất này:

$ git merge #91-fix-html-markup

nó sẽ không hoạt động như dự định bởi vì mọi thứ sau khi #bị bỏ qua, bởi vì #bắt đầu một bình luận nội tuyến.

Trong trường hợp này, bạn có thể đổi tên nhánh bỏ qua #hoặc sử dụng dấu ngoặc đơn để bao quanh tên nhánh : git merge '#91-fix-html-markup'.

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.