Làm thế nào để hái cherry từ một chi nhánh xa?


135

Tôi đang gặp khó khăn khi thực hiện một lựa chọn anh đào. Trên máy cục bộ của tôi, tôi hiện đang ở chi nhánh "chính chủ" của mình. Tôi muốn chọn cherry trong một cam kết từ một chi nhánh khác, được đặt tên là "ngựa vằn". Nhánh "ngựa vằn" là một nhánh từ xa.

Vì vậy, trạng thái git:

# On branch master
nothing to commit (working directory clean)

Ok, bây giờ tôi cố gắng chọn cherry mà tôi muốn:

git cherry-pick xyz
fatal: bad object xyz

trong đó "xyz" là chữ ký của cam kết mà tôi quan tâm, điều đó đã xảy ra trên nhánh "ngựa vằn".

Vì vậy, câu hỏi rõ ràng đầu tiên là, tại sao git không thể tìm thấy cam kết mà tôi đang tham khảo? Tôi thực sự không hiểu làm thế nào điều này hoạt động ở nơi đầu tiên phải trung thực. Có phải git lưu trữ một cái gì đó giống như một cơ sở dữ liệu của các xác nhận cục bộ trong thư mục làm việc của tôi, cho tất cả các chi nhánh khác không? Khi thực hiện lệnh cherry-pick, nó có đi và tìm kiếm cơ sở dữ liệu cục bộ đó để tìm cam kết mà tôi đang nói đến không?

Vì "ngựa vằn" là một nhánh từ xa, tôi đã nghĩ rằng tôi không có dữ liệu của nó tại địa phương. Thế là tôi chuyển ngành:

git checkout zebra
Switched to branch 'zebra'

Vì vậy, bây giờ ở đây trên máy cục bộ của tôi, tôi có thể thấy rằng các tệp trong thư mục phản ánh chính xác trạng thái của ngựa vằn. Tôi quay trở lại chủ, thử chọn lại cherry (hy vọng dữ liệu cam kết có sẵn ngay bây giờ), nhưng tôi gặp vấn đề tương tự.

Tôi đã có một sự hiểu lầm cơ bản về những gì đang diễn ra ở đây, bất kỳ trợ giúp sẽ là tuyệt vời.


2
Về mặt khái niệm mọi thứ có vẻ đúng. bạn có chắc là bạn đang sử dụng hàm băm chính xác (chữ ký như bạn gọi nó) của cam kết không? thử 'git show <hash>' để xác minh.
0xc0de

Xin chào, có tích cực - cả hai chi nhánh của tôi đều hoạt động trên github và tôi có thể sử dụng chúng để tìm các trang cam kết theo cách đó. Nếu tôi hiểu, trạng thái của máy của tôi cục bộ là git không thể tìm thấy hàm băm từ 'ngựa vằn' trong khi trong bối cảnh của 'chủ nhân'. Tôi có cần phải bằng cách nào đó nói với nó rằng "ngựa vằn" cũng tồn tại ở địa phương không?
dùng291701

oh và làm 'git show xyz' cũng cho cùng một lỗi "fatal: bad object". (và tôi đang thay thế xyz bằng hàm băm chính xác).
dùng291701

Và để làm rõ, tôi có thể sử dụng hàm băm 'xyz' của mình để xem cam kết trên github mà không gặp vấn đề gì, như: " github.com/me/test/commit/xyz ".
dùng291701

Câu trả lời:


195

Vì "ngựa vằn" là một nhánh từ xa, tôi đã nghĩ rằng tôi không có dữ liệu của nó tại địa phương.

Bạn đúng là bạn không có dữ liệu đúng, nhưng đã cố giải quyết nó sai cách. Để thu thập dữ liệu cục bộ từ một nguồn từ xa, bạn cần sử dụng git fetch. Khi bạn đã git checkout zebrachuyển sang bất cứ trạng thái nào của chi nhánh đó là lần cuối cùng bạn tìm nạp. Vì vậy, tìm nạp từ xa trước:

# fetch just the one remote
git fetch <remote>
# or fetch from all remotes
git fetch --all
# make sure you're back on the branch you want to cherry-pick to
git cherry-pick xyz


1
Đã thử cách tiếp cận này với cherry-pick một bản sửa lỗi ngược dòng trên Github và hóa ra hàm băm đã kiểm tra khác với hàm băm trên Github. Vì vậy, tôi đã phải kiểm tra, lấy băm và chọn cherry.
DustWolf

1
Thực sự thiếu ở đây một tùy chọn để vượt qua điều khiển từ xa trong cherry-pick như: git cherry-pick <remote> <hash>
Jared

làm việc tốt sau khi lấy chi nhánh từ xa. Cảm ơn :)
Adeel

có làm việc sau khi tìm nạp cho tôi quá. Thông tin thêm về git cherry-pick có sẵn tại atlassian.com/git/tutorials/cherry-pick
Seditesh M

12

Cũng như một phụ lục cho câu trả lời được chấp nhận của OP:

Nếu bạn có vấn đề với

fatal: bad object xxxxx

đó là bởi vì bạn không có quyền truy cập vào cam kết đó. Điều đó có nghĩa là bạn không có repo đó được lưu trữ cục bộ. Sau đó:

git remote add LABEL_FOR_THE_REPO REPO_YOU_WANT_THE_COMMIT_FROM
git fetch LABEL_FOR_THE_REPO
git cherry-pick xxxxxxx

Trong đó xxxxxxx là hàm băm cam kết bạn muốn.


hmm khi tôi đã thêm repo mà không có cờ ngược dòng?
Yêu tinh

10

Thêm repo từ xa (dưới dạng "foo") từ đó chúng tôi muốn chọn cherry

$ git remote add foo git://github.com/foo/bar.git

Lấy chi nhánh của họ

$ git fetch foo

Liệt kê các cam kết của họ (điều này sẽ liệt kê tất cả các cam kết trong tìm nạp foo)

$ git log foo/master

Cherry-pick cam kết bạn cần

$ git cherry-pick 97fedac

5

Sau khi hợp nhất một nhánh phát triển thành chủ, tôi thường xóa nhánh phát triển. Tuy nhiên, nếu tôi muốn chọn cherry trong nhánh phát triển, tôi phải sử dụng hàm băm xác nhận hợp nhất để tránh lỗi "đối tượng xấu".


3

Cần phải kéo cả dữ liệu nhánh trên ổ đĩa cục bộ của bạn trước.

Điều đang xảy ra là việc bạn cố gắng chọn cherry từ nhánh-a đến nhánh-b, trong đó bạn hiện đang ở nhánh-b, nhưng bản sao của nhánh-a chưa được cập nhật (bạn cần thực hiện thao tác git trên cả hai nhánh đầu tiên).

các bước:
- git checkout Branch-a
- git pull origin Branch-a
- git checkout Branch-b
- git pull origin Branch-b
- git cherry-pick <hash>

đầu ra:
[nhánh-b <hash>] dữ liệu nhật ký
Tác giả: Tác giả <
Tệp 1 Tác giả đã thay đổi, 1 lần chèn (+), 3 lần xóa (-)


1

Tôi đã gặp lỗi này sau khi sử dụng id xác nhận từ tab id yêu cầu kéo. Cam kết đó sau đó đã bị nghiền nát và sáp nhập. Trong yêu cầu kéo github, hãy tìm văn bản này: "đã hợp nhất xxxxxxx vào ..." thay vì cố gắng sử dụng id id từ tab xác nhận.


1

Các cam kết nên có mặt tại địa phương của bạn, kiểm tra bằng cách sử dụng git log.

Nếu cam kết không có thì hãy thử git fetchcập nhật cục bộ với điều khiển từ xa mới nhất.


0

Điều này cũng có thể dễ dàng đạt được với SourceTree:

  • kiểm tra chi nhánh chính của bạn
  • mở tab "Nhật ký / Lịch sử"
  • xác định vị trí cam kết xyz và nhấp chuột phải vào nó
  • nhấp vào "Hợp nhất ..."

làm xong :)


Điều này là không đúng. Bởi vì bây giờ bạn đang hợp nhất ĐẦU của chủ thành ngựa vằn thay vì chỉ cam kết được chọn.
Đầu bếp Pharaoh

0

Nếu bạn đã tìm nạp, nhưng điều này vẫn xảy ra, sau đây có thể là một lý do.

Nó có thể xảy ra rằng cam kết bạn đang cố gắng chọn, không còn thuộc về bất kỳ chi nhánh nào. Điều này có thể xảy ra khi bạn rebase.

Trong trường hợp như vậy, tại repo từ xa:

  1. git checkout xxxxx
  2. git checkout -b temp-branch

Sau đó trong repo của bạn, tìm nạp lại. Chi nhánh mới sẽ được tìm nạp, bao gồm cả cam kết đó.


0

Tôi đã giải quyết vấn đề này bằng cách đi vào chi nhánh với cam kết tôi muốn hái cherry.

git checkout <branch With Commit To Cherry-Pick>

sử dụng nhật ký để tìm cam kết băm

git log

khi bạn tìm thấy băm cắt và dán vào bảng ghi chú. Nếu sử dụng lệnh, chỉ cần cuộn lên để lấy hàm băm sau đó kiểm tra nhánh bạn muốn đặt cam kết.

git checkout < branch I Want To Place My Cherry-Picked-Hash In>

cuối cùng gọi cherry-pick từ git (lưu ý) -x là để thêm thông điệp chọn cherry của bạn vào bản gốc. "Khi ghi lại cam kết, hãy thêm một dòng có nội dung" (cherry được chọn từ cam kết) "vào thông điệp cam kết ban đầu để cho biết cam kết nào thay đổi này được chọn từ cherry."

git cherry-pick -x <your hash commit to add to the current branch>
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.