2010-01-17 30 views
6

Sau một vài giờ khá chơi với rebase, repo vẫn có vẻ khác với những gì tôi cần:Làm cách nào để sắp xếp lại/kết hợp các cam kết bằng cách sử dụng Git rebase?

Tôi muốn thực hiện các nhiệm vụ sau:
[một số trong số đó là OK trước khi tôi bắt đầu rối tung với rebase :(]

  • Move đỉnh cam kết ("Removed không liên quan ...") để trước khi nhánh (Ngay trên "sửa chữa cho # 226").
  • Kết hợp hai cam kết rằng đang ở trong 'xoắn/chi nhánh chính   "dấu phẩy" và "Đã di chuyển đã tải ..." phải là cùng một cam kết và tôi không cần thông báo cam kết o f "dấu phẩy".
  • Hợp nhất cam kết "Di chuyển đã tải" mới được kết hợp vào nhánh 'dự phòng' và loại bỏ 'xoắn'.
  • Di chuyển 'chế độ' thành vị trí hiện tại nói 'sao lưu'.
  • Thẻ "từ xa/nguồn gốc/chủ" có nghĩa là gì?

enter image description here

tôi nhận ra rằng đây là yêu cầu rất nhiều, nhưng xin vui lòng bao gồm các lệnh GIT thực tế.

Tôi không ngại đọc và tự mình thử, nhưng hơi bối rối bởi kết quả không phù hợp với những gì tôi mong đợi và tôi thực sự không muốn vô tình phá hủy bất kỳ cam kết nào.

+0

Câu hỏi này có tiêu đề khá xấu "git rebase help" và là một loạt các hoạt động riêng biệt mà bạn muốn thực hiện. Thử lặp lại điều này dưới dạng một câu hỏi duy nhất. Mục tiêu đầu tiên bạn đang cố gắng thực hiện, dưới hình thức một câu hỏi, có thể sẽ làm cho phần còn lại của họ rõ ràng. – Dustin

+0

Tôi không nghĩ rằng đó là một tiêu đề xấu, nó chắc chắn là một vấn đề đòi hỏi phải rebasing của cam kết. –

+1

Bạn có chắc chắn muốn kết hợp các nhánh 'twist' và' backup' không? Tôi hỏi bởi vì cả hai đều có cam kết với mô tả tìm kiếm giống hệt nhau. –

Trả lời

8

Đầu tiên, sắp xếp lại các cam kết backup.

# Safety, should be a no-op if your gitk snapshot is accurate 
git checkout backup 

# Temporary branch 
git branch backup-save backup 

# Move top commit onto 'Fix for #226: 
git rebase --onto origin/master HEAD^ 

# Go back to saved branch's parent (i.e. without the moved commit) 
git reset --hard backup-save^ 

# Rebase onto the moved commit ([email protected]{1} is where HEAD was 1 step 
# ago i.e. before the reset.) 
git rebase [email protected]{1} 

# Don't need the saved branch any more (although you might want 
# to keep it for a bit just in case). This deletes it: 
git branch -D backup-save 

Kết hợp hai lần commit trên xoắn, bỏ qua thông báo cam kết trên cùng.

git checkout twist 

git reset --soft HEAD^ 

# Just re-save the commit message, alternatively to skip the 
# editor step do this: git commit --amend -C HEAD 
git commit --amend 

Hợp nhất chi nhánh twist Hợp nhất chi nhánh backup, xóa nhánh xoắn.

git checkout backup 
git merge twist 
git branch -d twist 

Di chuyển master. Có nhiều cách ưa thích, nhưng điều này là đơn giản nhất. Tôi giả định rằng bạn muốn master trỏ đến vị trí đã chỉnh sửa backup và không phải vị trí ban đầu của nó.

git checkout master 
git reset --hard backup 

remote/origins/master là chi nhánh theo dõi từ xa và cho bạn biết nơi con trỏ chi nhánh cho master chi nhánh tại các kho lưu trữ từ xa origin là, hay đúng hơn là khi bạn cuối cùng lấy, đẩy hoặc kéo.

+0

Chà, bạn khỏe. 1. Các bước 'git checkout twist' không thành công trong việc kết hợp hai cam kết trong nhánh rẽ nhánh. Có phải nó được giả sử, hay tôi đang thiếu một cái gì đó?
2. Tại 'git merge twist'. Nó phàn nàn: CONFLICT (nội dung): Hợp nhất xung đột trong Source/Depender.js Hợp nhất tự động không thành công; sửa các xung đột và sau đó cam kết kết quả.
Làm cách nào để khắc phục xung đột? – SamGoody

+0

Chờ đã, tôi biết để sửa các xung đột với git add. Sẽ báo cáo lại sau một phút, hoặc tiếp tục làm rối tung lên, hoặc tất cả đều hạnh phúc. – SamGoody

+0

Trong khi tôi đã không hoàn toàn có được hai bước để làm việc, nó đã cho tôi đủ gần để đạt được mục tiêu. Tất cả mọi thứ bạn đã viết là rõ ràng và cho điểm. Cảm ơn rất nhiều. – SamGoody

6

Làm thế nào để đừng sợ

tôi muốn cho bạn thấy rằng không có vấn đề làm thế nào xấu bạn mess up, cam kết không bao giờ bị phá hủy * và bạn luôn có thể trở lại nơi mà bạn bắt đầu.

Tôi đã thực hiện một cây git giả có hình dạng giống như bạn mô tả:

Tôi bây giờ sẽ quét sạch ba cam kết cuối cùng từ các chi nhánh 'backup':

$ git log --oneline 
9b41f46 Removed extraneous whitespace 
981e2e8 Merged the "loadscripts" function 
005bc62 Pick up a few very fringe cases 
07e71d9 Merged "getDepsForScript" function 
... 
$ git reset --hard HEAD~3 
HEAD is now at 07e71d9 Merged "getDepsForScript" function 
$ git log --oneline 
07e71d9 Merged "getDepsForScript" function 
... 

Rất tiếc, điều đó thật tệ. Hãy quay lại nơi chúng ta bắt đầu. Trước tiên, hãy xem những gì chúng tôi đã làm:

$git reflog 
07e71d9 [email protected]{0}: HEAD~3: updating HEAD 
9b41f46 [email protected]{1}: commit: Removed extraneous whitespace 
... 

Bạn có thể thấy rằng khi chúng tôi đặt lại, tất cả git đã làm là thực hiện HEAD trỏ đến cam kết cũ đó. Nhưng không có cam kết thực sự bị mất - họ chỉ trở thành trẻ mồ côi, không phải là một phần của bất kỳ chi nhánh nào. Hãy đặt chúng trở thành một phần của nhánh "sao lưu" một lần nữa:

$ git reset --hard 9b41f46 
HEAD is now at 9b41f46 Removed extraneous whitespace 
$ git log --oneline 
9b41f46 Removed extraneous whitespace 
981e2e8 Merged the "loadscripts" function 
005bc62 Pick up a few very fringe cases 
07e71d9 Merged "getDepsForScript" function 
... 

Git nghĩa là không bao giờ phải nói bạn đang xin lỗi.

* Các vật thể lỏng lẻo cuối cùng cũng bị thu gom rác, nhưng không phải cho đến khi chúng được ít nhất hai tuần tuổi.

Cách làm những gì bạn muốn.

Đầu tiên chúng ta hãy kết hợp hai cam kết trong tổng thể:

$ git checkout master 
$ git rebase -i HEAD~2 

Git sẽ khởi động soạn thảo của bạn. Thay đổi này:

pick 6389f4e Moved "loaded" function out of "require". 
pick 41fb646 comma 

này:

pick 6389f4e Moved "loaded" function out of "require". 
s 41fb646 comma 

Và lưu. Git sẽ lại khởi chạy trình soạn thảo của bạn. Thay đổi này:

# This is a combination of two commits. 
# The first commit's message is: 

Moved "loaded" function out of "require". 

# This is the 2nd commit message: 

comma 

này:

Moved "loaded" function out of "require". 

và lưu lại.

Bây giờ chúng ta hãy sắp xếp lại các cam kết trong 'backup':

$ git checkout backup 
$ git rebase -i remotes/origin/master 

Khi soạn thảo của bạn bật lên, thay đổi này:

pick ec7f71c moved "loaded" function out of "require" 
pick 4a76897 Replaced maploaded event 
pick 07e71d9 Merged "getDepsForScript" function 
pick 005bc62 Pick up a few very fringe cases 
pick 981e2e8 Merged the "loadscripts" function 
pick 9b41f46 Removed extraneous whitespace    <----- 

này:

pick 9b41f46 Removed extraneous whitespace    <----- 
pick ec7f71c moved "loaded" function out of "require" 
pick 4a76897 Replaced maploaded event 
pick 07e71d9 Merged "getDepsForScript" function 
pick 005bc62 Pick up a few very fringe cases 
pick 981e2e8 Merged the "loadscripts" function 

và lưu lại.

Bây giờ anh đào-chọn sáp nhập "chuyển nạp" cam kết tắt của thầy và lên chi nhánh hiện tại ("backup")

$git cherry-pick master 

Make điểm bậc thầy với cùng cam kết là "backup"

$git checkout master 
$git reset --hard backup 

Loại bỏ các chi nhánh xoắn

$git branch -D twist 
+0

Tôi đánh giá rất cao công việc của bạn. Rất chi tiết và hữu ích. – SamGoody

+0

Sam, Niềm vui của tôi. Và đó không chỉ là một biểu hiện - tôi có rất nhiều niềm vui và học hỏi được nhiều khi tôi chọn một câu hỏi trên những gì tôi quen thuộc. –

+1

+1. Lệnh hữu ích khác để lấy lại các cam kết cũ: fsck (http://freeasinbeard.org/post/318519782/reflog-and-fsck-your-git-disaster-recovery-toolkit) – VonC

0

có một số điều bạn đang cố gắng để đạt được đây và đó là một chút không rõ ràng từ các sơ đồ cung cấp chính xác những gì là cần thiết nhưng các con trỏ sau đây có thể giúp:

  • Thay vì cố gắng để di chuyển chi nhánh của bạn, đầu tiên tôi sẽ kết hợp các cam kết mà bạn đã thực hiện trên chi nhánh, sau đó áp dụng cam kết cuối cùng cho nhánh chính kể từ đó cuối cùng những gì bạn đang nhắm đến. Bạn có thể phải giải quyết một số xung đột tại thời điểm này nhưng bạn sẽ phải làm điều đó anyway. Xem hai mẹo tiếp theo để biết thông tin về cách đạt được điều này.

  • Để kết hợp hai cam kết, bạn có thể thực hiện interactive rebase.

  • Để chọn một cam kết đơn lẻ từ một chi nhánh và áp dụng cho một nhánh khác, trong khi chi nhánh mục tiêu sử dụng git cherry-pick. Bạn có thể xóa chi nhánh cũ bằng cách sử dụng git branch -D twist khi hoàn tất.

Hy vọng những mẹo này sẽ giúp bạn trên đường đến mục tiêu của mình.

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