2012-01-03 29 views
31

cây địa phương của tôi đã tách ra từ các bậc thầy:git: phân nhánh; làm thế nào để tiến hành?

$ git status 
# On branch master 
# Your branch and 'origin/master' have diverged, 
# and have 7 and 3 different commit(s) each, respectively. 
# 
nothing to commit (working directory clean) 

tôi đã cố gắng git pull --rebase và thất bại:

$ git pull --rebase 
First, rewinding head to replay your work on top of it... 
Applying: * ... 
Using index info to reconstruct a base tree... 
Falling back to patching base and 3-way merge... 
Auto-merging ChangeLog 
CONFLICT (content): Merge conflict in ChangeLog 
Failed to merge in the changes. 
Patch failed at 0001 * ... 

Vì vậy, tôi hoàn nguyên với git rebase --abort và tôi giờ đang ở hình vuông 1.

Điều tôi muốn là:

  1. "Xuất" bản vá 7 của tôi vào các tệp khác có thể đọc được của con người (a la hg xuất).
  2. Làm cho cây của tôi một bản sao carbon gốc/chủ (a la hg dải).
  3. áp dụng lại 7 bản vá lỗi của tôi từng người một (a la hg nhập).

Tôi hiểu rằng git rebase --continue thực hiện việc này. Tôi đã làm điều đó và nó đã làm việc (sau khi một vài hợp nhất thủ công và một git thêm). Tuy nhiên, tôi muốn có thể thực hiện việc đó theo cách thủ công, vì vậy tôi tự hỏi các lệnh git tương ứng với các lệnh hg ở trên là gì.

Cảm ơn.

PS. Vui lòng không cho tôi biết rằng sử dụng tệp Thay đổiLog với git là ngu ngốc. Ngay cả khi có, nó không phải là tùy thuộc vào tôi.

+0

1. git merge origin/master. 2. git pull --no-rebase. Kể từ khi cam kết của bạn là rất lớn, kéo mà không rebase sẽ được dễ dàng hơn. –

Trả lời

43

Có, tất nhiên, một số cách bạn có thể thực hiện việc này theo cách thủ công. Bạn vẫn sẽ có những xung đột tương tự vì git về cơ bản là làm điều này cho bạn dưới mui xe. Nhưng nếu bạn muốn làm điều này bằng tay, đây là một vài cách.

Trước tiên, hãy xuất cam kết của bạn dưới dạng một loạt các bản vá. Cách dễ nhất để thực hiện việc này là sử dụng git format-patch:

git format-patch -M @{upstream} 

sẽ tạo 7 tệp vá - một cho mỗi cam kết của bạn. (Lưu ý rằng "@ {upstream}" là chữ - nó không phải là một tính năng nổi tiếng của git.) Điều này tốt hơn là thu được kết quả của git diff vì tất cả thông tin cam kết (tác giả, ngày tháng, thư, v.v.) là bảo quản.

Sau đó, bạn có thể thiết lập lại kho lưu trữ của bạn để phù hợp với thượng nguồn:

git reset --hard @{upstream} 

Sau đó, bạn có thể tái áp dụng các bản vá lỗi của bạn sử dụng git am - hoặc cùng một lúc hoặc tất cả cùng một lúc.

git am 0001-blah-blah.patch 
git am 0002-blah-blah.patch 
... 

Một lựa chọn thứ hai sẽ là để tạo ra một chi nhánh tùng với công việc của bạn trên đó:

git branch scrap 

Sau đó thiết lập lại chi nhánh của bạn về phía thượng lưu:

git reset --hard @{upstream} 

Sau đó anh đào-chọn cam kết qua:

git cherry-pick scrap~6 
git cherry-pick scrap~5 
git cherry-pick scrap~4 
... 

Sau đó, đổ rác vào nhánh phế liệu:

git branch -D scrap 
+4

Thay cho "@ {upstream}", bạn thậm chí có thể sử dụng "@ {u}". –

+0

Điều này cực kỳ hiệu quả và sạch sẽ - bạn kết thúc với một lịch sử tuyến tính. – hauron

6

Git nói rằng nó đã cố gắng làm chính xác những gì bạn muốn (áp dụng lại các bản vá lỗi của bạn trên những thay đổi mới nhất từ ​​nguồn gốc/chủ) nhưng không thành công với xung đột. Ngay sau khi git pull --rebase xung đột mở trình chỉnh sửa với các tệp bị xung đột (git status sẽ liệt kê những điều này trong "cả hai đã thay đổi") và giải quyết xung đột, được đánh dấu bằng lingua khác biệt chuẩn. Khi bạn hoàn tất việc giải quyết xung đột, hãy ném vào một số git rebase --continue (hoặc git rebase --skip nếu độ phân giải của bạn không có thay đổi).

Đọc về anh ấy tại Stackexchange documentation for 'Resolving merge conflicts after a Git rebase'.

+0

Git khá tốt khi hợp nhất (hoặc, tự động giải quyết "xung đột") và áp dụng lại các bản vá lỗi, nhưng than ôi, đôi khi nó cần sự giúp đỡ của bạn.Trong những trường hợp này, theo kinh nghiệm của tôi, tôi biết không có công cụ nào khác làm tốt hơn. Bạn thực sự cần phải giải quyết các xung đột này theo cách thủ công. – wilhelmtell

+0

Điểm tốt - hãy nhớ xem [git rerere] (http://progit.org/2010/03/08/rerere.html). –

+0

Điều này không trả lời được câu hỏi. – sds

15

Bạn đã thử git merge origin/master chưa?

Thay đổi từ xa của bạn được lưu trữ trong chi nhánh origin/master. (Hoặc nó sẽ, nếu bạn làm git fetch.) Chỉ cần hợp nhất hai chi nhánh - masterorigin/master - giống như bất kỳ hai nhánh nào và giải quyết xung đột (nếu có).

Điều này có thể giúp bạn nếu bạn cần biết cách giải quyết xung đột git.

How to resolve merge conflicts in Git?

+0

Được thăng hạng. Tôi đã có chính xác cùng một vấn đề và điều này cố định nó. Cá nhân tôi không thích vi hoặc vim vì vậy tôi đã thay đổi trình soạn thảo mặc định thành nano. Google để được hướng dẫn. – Cocoadelica

0

Dưới đây là một số câu trả lời tốt để cùng một vấn đề (chỉ không có xung đột giải quyết):

master branch and 'origin/master' have diverged, how to 'undiverge' branches'?

Trước tiên, bạn có thể muốn xem lại những gì đã được thay đổi trên tổng thể từ xa trong so sánh với phiên bản địa phương của bạn:

git log HEAD..origin/master 

Để khắc phục sự cố thực sự của bạn, nó sẽ chuyển thành mẫu dòng e mà wilhelmtell đề xuất:

git pull --rebase 

Như bạn đã nói, bạn sẽ nhận được xung đột.

Xung đột giải quyết là sự cố định kỳ. Nếu bạn chưa thực hiện, bạn có thể xem git mergetool (xem git help mergetool để biết chi tiết). Để được hỗ trợ đồ họa, tôi khuyên bạn nên ghi đè cấu hình merge.tool. Ví dụ, nếu bạn muốn sử dụng meld cho hòa trộn 3 chiều, bạn có thể sử dụng:

git config --global merge.tool meld 

Vì vậy, sau khi bạn giải quyết các xung đột, những gì đã git pull --rebase thực hiện? Nó sáp nhập tất cả các thay đổi từ nguồn gốc/chủ vào tổng thể địa phương của bạn, và phát lại các thay đổi của bạn trên đầu trang của nó. Xin chúc mừng, bạn đã trở lại bình thường.

+0

khi "git pull --rebase", nó cho biết "lỗi: cho ăn chưa sửa đổi ... để phân biệt Không thể kéo với rebase: Chỉ mục của bạn chứa các thay đổi không được cam kết. Vui lòng cam kết hoặc stash chúng", nhưng khi "git commit", nó "Chi nhánh của bạn và" nguồn gốc/chủ "đã phân tách, và có 1 và 1 khác nhau cam kết mỗi tương ứng (sử dụng" git pull "để hợp nhất chi nhánh từ xa vào máy của bạn) không có gì để cam kết, làm việc thư mục sạch" – diyism

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