Nhánh Git phân kỳ sau khi rebase


112

Tôi đã khôi phục lại một chi nhánh cục bộ đã được đẩy.

Git đang thông báo rằng chi nhánh và điều khiển từ xa của tôi đã khác nhau và rằng:

"và có 109 và 73 cam kết khác nhau, tương ứng"

Việc đẩy chi nhánh của tôi có giải quyết được điều này không - tức là điều này có được mong đợi sau khi rebase không?


Tôi có cùng một vấn đề. Chúng ta có thể nói rằng "cách phải làm" là rebase local branch và chỉ sau đó push không?
Mher Didaryan,

Câu trả lời:


154

Khi bạn căn cứ lại một nhánh, bạn phải viết lại các cam kết cho bất kỳ cam kết nào nằm trên các cam kết trong nhánh mà bạn đang khôi phục. Điều này là do một trong những thuộc tính của một cam kết là cha (hoặc cha mẹ) của nó. Khi bạn rebase, bạn đang thay đổi cấp độ gốc của cam kết cục bộ cũ nhất trên chi nhánh của bạn - và do đó thay đổi các băm cam kết của tất cả các cam kết cục bộ của bạn, vì thay đổi này xuất hiện thông qua các cam kết chuyển tiếp.

Vì bạn đã đẩy nhánh, bạn nên hợp nhất trong nhánh nguồn, thay vì khôi phục lại nó. Có thể "ép đẩy" nhánh mới của bạn (bằng cách sử dụng -fcờ), nhưng một cú thúc thông thường sẽ không hoạt động, vì tính toàn vẹn của lịch sử các nhánh sẽ bị xáo trộn. Nếu bạn đang cộng tác với những người khác trong nhánh này, ép buộc là một ý tưởng tồi, vì nó sẽ khiến các cộng tác viên khác trở nên rất bối rối khi lịch sử của họ đột nhiên không khớp.

TL; DR - Nếu bạn không cộng tác, hãy đẩy nhánh bằng push -f. Nếu đúng như vậy, hãy đặt lại nhánh về trạng thái trước đó và hợp nhất trong nhánh nguồn, thay vào đó.


1
"Vì bạn đã đẩy nhánh, bạn nên hợp nhất trong nhánh nguồn" - tại sao vậy?
hammett

1
@HamiltonVerissimo Câu đầu tiên của Jason: "Khi bạn rebase một nhánh, bạn phải viết lại các cam kết cho bất kỳ cam kết nào cao hơn các cam kết trong nhánh mà bạn đang khôi phục." Mặc dù các thay đổi được ghi lại trong các cam kết "ở trên" có cùng nội dung logic, chúng đang được áp dụng cho một cơ sở khác và do đó là các cam kết khác nhau với các hàm băm khác nhau. Nếu các nhà phát triển khác đang làm việc từ nhánh đã được giảm giá trước thì việc thực hiện git push -f sẽ cực kỳ ảnh hưởng đến quy trình làm việc của họ. Vì vậy, vì chi nhánh này đã được đẩy lên một nguồn công khai, anh ta nên được sáp nhập.
awolf

4
bạn cũng có thể sử dụng push --force-with-cho thuê nếu bạn không chắc liệu có ai khác đã đẩy một cái gì đó hay không.
Bảng điều khiển

1
@ jason-lebrun Không phải là nhược điểm của việc hợp nhất các thay đổi ngược dòng mà bạn có thể ghi đè công việc của mình mà không cần cảnh báo? Xung đột hợp nhất có được phát hiện giống như khi khôi phục không? Ví dụ: nếu tôi xóa một phần khỏi tệp trong chi nhánh của mình vì nó không còn cần thiết nữa, nhưng ai đó đã thực hiện một thay đổi nhỏ đối với cùng một phần ở phía trên, chẳng hạn như xóa một số khoảng trắng hoặc một số hành động tìm / thay thế toàn cục, thì không. hợp nhất mà trên đầu chi nhánh của tôi thay thế việc xóa của tôi bằng phiên bản đã thay đổi tầm thường của họ?
Chris Bloom

1
Sáp nhập chi nhánh khác với của bạn không phải là một ý tưởng tồi phải không? Ví dụ: Hợp nhất tổng thể vào một nhánh tính năng - điều đó sẽ không tạo ra một cam kết mới cho điều đó? Điều đó sẽ không dẫn đến một cam kết bổ sung khi tính năng này phân nhánh nếu hợp nhất để làm chủ sau này?
Ross

55

Tất cả các cam kết của bạn đã thay đổi id, do đó, sự chuyển hướng không thực sự là một sự khác biệt.

Để giải quyết vấn đề, bạn phải ghi đè nhánh từ xa của mình:

git push -f origin experiment

http://git-scm.com/book/ch3-6.html

Giải trình:

Hãy xem trong hình này C3 không được đặt là C3 sau rebase, mà là C3 '. Điều này là do nó không chính xác là C3, nhưng nó có tất cả các thay đổi mã của nó.

Rebase

Trên hình ảnh khác này, bạn sẽ có được bức tranh về những gì một rebase được nhìn thấy khi có điều khiển từ xa và tại sao có sự chuyển hướng.

phân kỳ và đẩy git

Trong mọi trường hợp, sau khi bạn thực hiện ép buộc, nó sẽ cho bạn biết rằng nó đã thực hiện một (buộc cập nhật), bạn sẽ ổn ở điểm đó.

Kiểm tra liên kết ở trên cùng và tìm kiếm "git push --force". Bạn sẽ thấy một lời giải thích chi tiết hơn.


3
Đúng vậy. Tôi đoán điều này giải quyết được vấn đề. Tuy nhiên, lực đẩy có thể không hoạt động khi bạn đang làm việc cùng trong một nhóm khi thúc đẩy của bạn có thể ghi đè lên bất kỳ công việc nào gần đây do người khác đẩy. Tôi nói đúng chứ?
Hari Krishna Ganji

Nó có thể không có tác dụng mong muốn. Đảm bảo rằng bạn hợp nhất các thay đổi của mình 'tua đi nhanh' trước khi thực hiện rebase.
mimoralea

1

Tôi đã thành công với phân kỳ rebase cho một cú hích bằng cách làm như sau:

git checkout mybranch
git pull
git push origin mybranch

Lực kéo đã giải quyết sự khác biệt.

TRƯỚC khi kéo

Your branch and 'origin/mybranch' have diverged,
and have 2 and 1 different commit(s) each, respectively.

Đầu ra PULL

Hợp nhất được thực hiện bằng đệ quy. mypath / myfile.py | 12 +++++++++++ - 1 tệp đã thay đổi, 11 lần chèn (+), 1 lần xóa (-)

SAU KHI kéo

Chi nhánh của bạn đi trước 'origin / mybranch' 3 lần cam kết.

SAU KHI PUSH

mybranch đi trước nhánh 3, vẫn có thông báo kết hợp yêu cầu kéo mở được thêm vào lịch sử cam kết Hợp nhất nhánh mybranch của remote vào mybranch

Tôi giả định đây có thể là những gì lực đẩy thực hiện và tôi chưa xác minh.

Như những người khác đã nói, tránh rebase nếu bạn đã có một yêu cầu kéo mở. Tôi đang cung cấp ví dụ này như một cái gì đó phù hợp với tôi.


1

Điều này có thể được khắc phục mà không bị thúc ép bằng cách khôi phục nhánh mục tiêu vào nhánh cục bộ hiện tại của bạn, chuyển sang nhánh mục tiêu của bạn, sau đó khôi phục nhánh cục bộ của bạn vào mục tiêu. Điều này không khác nhau vì (các) cam kết có thể bị thiếu được thêm vào và không cần phải tạo nữa. Ví dụ để giải thích dễ dàng hơn:

  1. chi nhánh chính đang phát triển
  2. Bạn kiểm tra một tính năng nhánh mới / doing_stuff
  3. Một thành viên trong nhóm thúc đẩy một cam kết mới để phát triển

Nếu bạn KHÔNG cập nhật nhánh phát triển của mình thì "git checkout Develop" && "git rebase feature / doing_stuff" sẽ hoạt động bình thường vì không có cam kết nào được thêm kể từ khi bạn thanh toán. Tuy nhiên, nếu bạn đã kiểm tra phát triển và kéo xuống cam kết mới thì bạn sẽ thấy sự khác biệt này nếu bạn cố gắng căn cứ lại do một cam kết mới được nhìn thấy. Một cách khắc phục dễ dàng mà không cần thúc ép (thường không phải là ý kiến ​​hay trong môi trường đồng đội) là:

  1. git checkout feature / doing_stuff
  2. git rebase phát triển
  3. phát triển thanh toán git
  4. git rebase feature / doing_stuff

Rebase từ bước 2 đưa cam kết bị thiếu vào tính năng / doing_stuff để khi bước 4 xuất hiện, nó sẽ được cập nhật và không cần tạo cam kết mới cho thay đổi.

Đây là một giải pháp mà tôi biết là hiệu quả bởi vì tôi vừa mới bắt gặp và thực hiện các bước ở trên để đẩy phát triển thành công mà không cần ép buộc. Tôi làm việc trong một nhóm hơn 50 nhà phát triển nên không được phép ép buộc bất cứ thứ gì khác ngoài các nhánh thử nghiệm của riêng tôi, vì vậy tôi đã phải tìm cách giải quyết.

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.