2012-01-26 25 views
12

Giả sử kho Git của tôi ban đầu có hai nhánh: Foo và Bar.Rebase commit merge

 
... ─ Foo 

... ─ Bar 

Tôi tạo nhánh thứ ba, FooBar trong đó tôi cam kết hợp nhất hai nhánh khác.

 
... ─ Foo ──┐ 
      FooBar 
... ─ Bar ──┘ 

FooBar hiện là một cam kết trước cả Foo và Bar. Tiếp theo, tôi làm một số công việc nhiều hơn, cam kết một vài lần trên Foo chỉ.

 
... ── A ───┬── B ── C ── D ── Foo 
      FooBar 
... ─ Bar ──┘ 

Câu hỏi đặt ra là: kể từ khi cha mẹ đầu tiên của chi nhánh Foobar không còn Foo, tôi có thể rebase hợp nhất cam kết trong ngành Foobar để một lần nữa có Foo và Bar như hai cha mẹ của nó? Nói cách khác, tôi có thể kết hợp sự phát triển trong Foo vào FooBar đã hợp nhất trước đó cùng với Thanh không thay đổi không?

 
... ── A ── B ── C ── D ── Foo ──┐ 
           FooBar 
... ─ Bar ───────────────────────┘ 
+0

Xem thêm [sử dụng git-thay thế để thay đổi con trỏ mẹ] (http://stackoverflow.com/a/3811217/90527), mặc dù điều này có các hậu quả khác. – outis

+0

Xem thêm [Làm cách nào để sử dụng git rebase -i sau khi git hợp nhất mà không làm rối tung mọi thứ?] (Http://stackoverflow.com/q/4152936/90527) – outis

Trả lời

1

Bạn không thể rebase theo chi nhánh FooBar mà không thay đổi định nghĩa FooBar. Những gì bạn có thể làm là hợp nhất FooBarFoo. Điều đó sẽ có cùng nội dung mà bạn mong muốn.

+0

Có, nhưng vấn đề là tránh các cam kết hợp nhất. Đó là lý do tại sao tôi muốn rebase 'BranchFooBar'. – nccc

+0

Có lẽ tôi đang bối rối với những gì bạn muốn. Bạn nói rằng bạn muốn tránh hợp nhất các cam kết, nhưng tôi giải thích câu hỏi của bạn khi bạn muốn kết quả cuối cùng là một cam kết hợp nhất giữa 'branchFoo' và' branchBar'. – Andy

+0

Bạn nói đúng, điều này chưa đủ rõ ràng. Tôi muốn tránh một cam kết * 2 * hợp nhất. 'BranchFooBar' sẽ luôn là một commit hợp nhất, nhưng tôi muốn nó là * only * merge commit với' BranchFoo' và 'BranchBar' làm cha mẹ. – nccc

0

Về cơ bản, bạn đang cố xóa tất cả các dấu vết của quá trình hợp nhất đã được tạo trước đó.

Nếu bạn thực sự muốn vứt bỏ tất cả các cam kết rằng chỉ tồn tại trong FooBar (và trong thư mục làm việc), sau đó tiến hành như sau: đầu tiên làm git checkout FooBar, sau đó làm cho git quên nó là lịch sử và làm git reset --hard Foo (nếu bạn có ý định hợp nhất Bar vào Foo). Sau đó, bạn tạo lại hợp nhất với git merge Bar.

12

Tôi nhận ra đây là một chủ đề khá cũ nhưng vì tôi đã tìm thấy câu hỏi này trong khi phải đối mặt với một tình huống tương tự, tôi cũng có thể nói những gì tôi đã sử dụng cuối cùng.

git checkout FooBar 
git rebase -p --onto Foo A 

Tôi đã cố gắng sử dụng tên từ câu hỏi gốc. Lưu ý đặc biệt là A có nghĩa là cam kết được đánh dấu là A trong nghệ thuật ascii. Bạn có thể sử dụng hàm băm của cam kết thay thế hoặc bất kỳ cách nào khác để trỏ đến cam kết trong đó các chi nhánh FooFooBar ban đầu riêng biệt.

Cờ -p còn được gọi là --preserve-merges và nó thực hiện khá nhiều điều nó nói.

Lưu ý rằng chi nhánh Bar không đóng vai trò ở đây để dòng cam kết có thể là chi nhánh được đặt tên hoặc sau đó không - nó không có sự khác biệt.

+3

Lưu ý rằng điều này sẽ không giữ bất kỳ thay đổi nào được thực hiện trong cam kết hợp nhất. – Tgr

+2

Cảm ơn, điều này đã giúp chúng tôi rất nhiều. Điều thực sự quan trọng cần lưu ý là 'A' là cam kết cuối cùng của chi nhánh mục tiêu vẫn được đưa vào hợp nhất gốc. – Dibbeke

+1

đây phải là câu trả lời được chấp nhận! – wutzebaer

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