Làm thế nào để đối phó với cảnh báo git này? “Không khuyến khích việc kéo mà không chỉ rõ cách điều hòa các nhánh khác nhau”


123

Sau khi git pull origin mastertôi nhận được thông báo sau:

warning: Pulling without specifying how to reconcile divergent branches is
discouraged. You can squelch this message by running one of the following
commands sometime before your next pull:

  git config pull.rebase false  # merge (the default strategy)
  git config pull.rebase true   # rebase
  git config pull.ff only       # fast-forward only

You can replace "git config" with "git config --global" to set a default
preference for all repositories. You can also pass --rebase, --no-rebase,
or --ff-only on the command line to override the configured default per
invocation.

remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 51.49 KiB | 850.00 KiB/s, done.

Sau đó, kéo đã được thực hiện thành công. Nhưng tôi vẫn nghi ngờ về tin nhắn này.
Điều tốt nhất để làm trong trường hợp này là gì?


1
Gửi báo cáo lỗi rằng cảnh báo khó hiểu. Một tùy chọn nên được "khuyến nghị" và cảnh báo chỉ hiển thị theo yêu cầu chứ không phải chỉ vì một thay đổi phiên bản đã xảy ra. Các tập lệnh tự động của Lot có thể bị phá vỡ ngay bây giờ với hành vi không mong muốn này.
Wolfgang Fahl

1
@WolfgangFahl, cảnh báo sẽ không ảnh hưởng đến bất kỳ tập lệnh nào vì nó tiếp tục giữ nguyên hành vi mặc định cho đến khi được thay đổi rõ ràng. Nó sẽ không khiến kéo trả về một mã thoát khác 0 (vì nó là một cảnh báo, không phải là một lỗi). Một vài tập lệnh CI / CD mà tôi đã triển khai trên các máy chủ khác nhau tiếp tục hoạt động với tỷ lệ thành công không bị ảnh hưởng.
Qumber

@Qumber - cảm ơn đã nhận xét. Các mục nhập Crontab, ví dụ: sẽ bắt đầu gửi e-mail nếu đầu ra xuất hiện không có ở đó hoặc có thể được lọc bằng một grep đơn giản. Đầu ra không mong muốn có thể có tất cả các loại tác dụng phụ.
Wolfgang Fahl

@WolfgangFahl, Mỗi lần kéo thường có một số đầu ra khác nhau. Vì vậy, bất kỳ kịch bản nào chỉ phụ thuộc vào đó có thể được viết rất tệ. Ngoài ra, không nên nâng cấp môi trường sản xuất mà không có thử nghiệm rộng rãi. Tôi không muốn nâng cấp sản phẩm nào cả. Thay vào đó, tôi tạo một phiên bản mới với mọi thứ mới nhất, lưu trữ các ứng dụng của tôi ở đó, kiểm tra mọi thứ và sau đó đưa nó vào sản xuất.
Qumber

Câu trả lời:


137

Trong chế độ mặc định của nó, git pull là viết tắt của git fetch, sau đó là git merge FETCH_HEAD.

Khi bạn thực hiện một git pull origin master, hãy
git pullthực hiện hợp nhất, điều này thường tạo ra một cam kết hợp nhất. Do đó, theo mặc định, việc kéo từ điều khiển từ xa KHÔNG phải là một thao tác vô hại: nó có thể tạo ra một cam kết mới chưa tồn tại trước đây. Hành vi này có thể gây nhầm lẫn cho người dùng, vì những gì cảm thấy giống như một hoạt động tải xuống vô hại thực sự thay đổi lịch sử cam kết theo những cách không thể đoán trước.

Để tránh điều này, bạn cần

git pull --ff-only

(hay không? đọc tiếp để xem cái nào phù hợp với nhu cầu của bạn)

Với git pull --ff-only, Git sẽ cập nhật chi nhánh của bạn chỉ khi nó có thể được "chuyển tiếp nhanh" mà không cần tạo cam kết mới. Nếu điều này không thể được thực hiện, git pull --ff-onlychỉ cần hủy bỏ với một thông báo lỗi.

Bạn có thể định cấu hình ứng dụng khách Git của mình để luôn sử dụng --ff-onlytheo mặc định, vì vậy bạn sẽ có hành vi này ngay cả khi bạn quên cờ dòng lệnh:

git config --global pull.ff only

Lưu ý: --globalCờ áp dụng thay đổi cho tất cả các kho lưu trữ trên máy của bạn. Nếu bạn muốn hành vi này chỉ cho kho lưu trữ bạn đang ở, hãy bỏ qua cờ.

Lấy từ đây



Cảnh báo này đã được thêm vào trong Git 2.27, như được chỉ ra bởi Joe trong câu trả lời của anh ấy.

Đây là cảnh báo hoàn chỉnh trông như thế nào:

Không khuyến khích việc kéo mà không xác định rõ cách điều hòa các nhánh phân kỳ. Bạn có thể bỏ qua thông báo này bằng cách chạy một trong các lệnh sau đây vào lúc nào đó trước lần kéo tiếp theo:

git config pull.rebase false # merge (chiến lược mặc định)
git config pull.rebase true # rebase
git config pull.ff only # fast-forward only

Bạn có thể thay thế "git config" bằng "git config --global" để đặt tùy chọn mặc định cho tất cả các kho. Bạn cũng có thể chuyển --rebase, --no-rebase hoặc --ff-only trên dòng lệnh để ghi đè mặc định đã định cấu hình cho mỗi lần gọi.

Cảnh báo hiển thị ba lệnh dưới dạng tùy chọn, tất cả những lệnh này sẽ ngăn cảnh báo. Nhưng chúng phục vụ các mục đích khác nhau:

git config pull.rebase false     # merge (the default strategy)

Điều này giữ nguyên hành vi mặc định và loại bỏ cảnh báo.

git config pull.rebase true      # rebase

Điều này thực sự cam kết trên đầu nhánh từ xa, duy trì một nhánh duy nhất cả cục bộ và từ xa (không giống như hành vi mặc định có liên quan đến hai nhánh khác nhau - một trên cục bộ và một trên từ xa - và để kết hợp cả hai, hợp nhất được thực hiện ).

git config pull.ff only          # fast-forward only

Điều này chỉ thực hiện kéo nếu nhánh cục bộ có thể được chuyển tiếp nhanh. Nếu không, nó chỉ dừng lại với một thông báo lỗi (và không tạo ra bất kỳ cam kết nào).


Cập nhật:

Nếu bạn có Git 2.29trở lên, bây giờ bạn có thể thiết lập pull.ffđể false, truehoặc onlyđể thoát khỏi cảnh báo.

git config pull.ff

true- Đây là hành vi mặc định. Kéo được chuyển tiếp nhanh nếu có thể, nếu không, nó được hợp nhất.

git config pull.ff false

false - Kéo không bao giờ được tua đi nhanh chóng và một hợp nhất luôn được tạo.

git config pull.ff only

only - Kéo được tua đi nhanh nếu có thể, nếu không hoạt động bị hủy bỏ với thông báo lỗi.


2
Tôi đánh giá cao thời gian và nỗ lực mà bạn đã bỏ ra cho câu trả lời của mình, nhưng thành thật mà nói thì tôi vẫn hoàn toàn không thể hiểu được điều này.
Jared Nedzel

1
Như đã nhận xét ở đây , cảnh báo không bị ảnh hưởng bởi việc nhánh có thực sự phân kỳ hay không . Đầu tiên "Chi nhánh của bạn có thể đang phân kỳ." có thể gây hiểu lầm.
Joe

2
Tôi phải nói rằng, ba tùy chọn trong tin nhắn không hoạt động để tôi nhấn tin nhắn. Tuy nhiên câu trả lời ở đây ( git config --global pull.ff only) đã làm .
DiskJunky

1
Aha! Cảm ơn @Qumber. Tôi đã thử pull.rebase false, nhưng nó không hoạt động như mô tả. Nó luôn tạo ra một cam kết hợp nhất và không bao giờ chuyển tiếp nhanh. Nguyên nhân sâu xa là do tôi đã merge.ff falsecài đặt. Sau khi xóa cài đặt đó, nó sẽ chuyển tiếp nhanh khi cần. Tài liệu ở đây (gần giống với tài liệu git pull )
stwr667

1
Bạn đã bao gồm tùy chọn Git 2.29 mà tôi đề cập bên dưới, điểm tốt. Đã ủng hộ.
VonC

56

Đây là một cảnh báo mới được thêm vào Git 2.27 :

 * "git pull" issues a warning message until the pull.rebase
   configuration variable is explicitly given, which some existing
   users may find annoying---those who prefer not to rebase need to
   set the variable to false to squelch the warning.

Để loại bỏ các cảnh báo, thiết lập một trong những giá trị đề nghị với hành vi mặc định ưa thích của bạn cho git pullnếu bạn không xác định hành vi trên dòng lệnh (sử dụng --ff, --no-ff, --ff-only, --rebase). Trong mọi trường hợp, gitsẽ cố gắng hợp nhất tua đi nhanh ( Chuyển tiếp nhanh git là gì? ) Nếu có thể. Cài đặt kiểm soát những gì sẽ xảy ra khi có những thay đổi trong nhánh của bạn nhưng không có trong nhánh ở xa.

  git config pull.rebase false  # merge (the default strategy)

Đây là hành vi mặc định hiện có; đặt điều này để không có cảnh báo và không có thay đổi trong hành vi; gitsẽ hợp nhất chi nhánh từ xa vào chi nhánh cục bộ của bạn.

  git config pull.rebase true   # rebase

Tại đây, gitsẽ cố gắng căn cứ lại các thay đổi của bạn trên đầu nhánh từ xa. Xem Khi nào tôi nên sử dụng git pull --rebase? để biết thêm chi tiết về lý do tại sao bạn có thể muốn điều đó.

  git config pull.ff only       # fast-forward only

Nếu không thể hợp nhất tua đi nhanh, gitsẽ từ chối tiếp tục. Như Sự khác biệt giữa dấu ngoặc kép git pull --rebase và git pull --ff :

Từ chối hợp nhất và thoát với trạng thái khác không trừ khi HEAD hiện tại đã được cập nhật hoặc việc hợp nhất có thể được giải quyết dưới dạng tua nhanh


18
Đây thực sự là câu trả lời chính xác nhất, vì nó giải thích tại sao mọi người (như tôi) đột nhiên nhìn thấy cảnh báo này sau gần một thập kỷ sử dụng git. Tuy nhiên, sẽ hữu ích nếu một số hướng dẫn được đưa ra về các tùy chọn được cung cấp. ví dụ: chỉ ra rằng việc đặt pull.ff thành "only" không ngăn bạn thực hiện "pull --rebase" để ghi đè nó.
kdopen

Sự khác biệt giữa pull.rebase = truevà là branch.autoSetupRebase = alwaysgì?
tekumara


1
"khi có những thay đổi trong chi nhánh của bạn nhưng không có mặt trong chi nhánh ở xa." Sau đó, có vẻ như với tôi rằng git chỉ nên ném cảnh báo này nếu đúng như vậy. Nếu tôi đang kéo dòng chính của mình (và dòng chính được sử dụng đúng cách) thì tôi không cần phải lo lắng về điều đó.
Keith Tyler

4
@Joe Tôi thích câu trả lời của bạn và nghĩ đó là câu trả lời đúng , nhưng bạn thấy điều này bất kể git có thực sự làm được gì hay không. Tôi cảm thấy rằng thời điểm thích hợp để đưa ra cảnh báo này là nếu git phải làm gì đó, thì thông báo này sẽ không thành công. Không chỉ người dùng spam với tin nhắn này từ trước. Tuy nhiên, một điều khác góp phần vào mối quan hệ yêu / ghét của tôi với git.
Jon V

6

git config pull.ff onlyhoặc tương đương git pull --ff-onlylà an toàn nhất. Lý do là một rebase có thể ghi đè lịch sử và có thể gây mất cam kết nếu một nhà phát triển khác đã ép buộc đến cùng một nhánh.

Nhưng tất cả chúng đều hợp lệ.


3

Lưu ý: Trước đó chúng tôi đã dạy " git pull" ( man ) để cảnh báo khi người dùng không cho biết lịch sử cần được hợp nhất, khôi phục hoặc chỉ chấp nhận chuyển tiếp nhanh, nhưng cảnh báo sẽ kích hoạt cho những người đã đặt pull.ffbiến cấu hình.

Điều này không còn xảy ra nữa (có nghĩa là: không còn cảnh báo nữa ) với Git 2.29 (Q4 2020).

Xem cam kết 54200ce (24 tháng 9 năm 2020) bởi Alex Henrie ( alexhenrie) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- in commit 299deea , 29/09/2020)

pull: không cảnh báo nếu pull.ffđã được thiết lập

Người ký tên: Alex Henrie

Người dùng đủ hiểu để thiết lập pull.ffkhông cần thêm hướng dẫn.

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.