Git rebase: xung đột tiếp tục chặn tiến trình


120

Tôi có một nhánh git (được gọi là v4), được tạo từ chủ mới hôm qua. Có một vài thay đổi đối với master mà tôi muốn chuyển sang phiên bản 4. Vì vậy, trong v4, tôi đã cố gắng thực hiện rebase từ master và một tệp vẫn tiếp tục làm rối tung mọi thứ: tệp văn bản một dòng, chứa số phiên bản. Tệp này app/views/common/version.txt, trước khi khôi phục có chứa văn bản này:

v1.4-alpha-02

Đây là những gì tôi đang làm:

> git rebase master
First, rewinding head to replay your work on top of it...
Applying: new version, new branch
error: patch failed: app/views/common/version.txt:1
error: app/views/common/version.txt: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging app/views/common/version.txt
CONFLICT (content): Merge conflict in app/views/common/version.txt
Failed to merge in the changes.
Patch failed at 0001 new version, new branch

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

Các version.txtbây giờ trông như thế này:

<<<<<<< HEAD:app/views/common/version.txt
v1.4-alpha-02
=======
v1.4-alpha-01
>>>>>>> new version, new branch:app/views/common/version.txt

Vì vậy, tôi dọn dẹp nó và nó trông như thế này bây giờ:

v1.4-alpha-02

và sau đó tôi cố gắng tiếp tục: lúc đầu tôi thử cam kết:

> git commit -a -m "merged"
# Not currently on any branch.
nothing to commit (working directory clean)

Không có may mắn ở đó. Vì vậy, tôi đã cố gắng thêm tệp:

git add app/views/common/version.txt

Không phản hồi. Tôi đoán không có tin tức nào là tin tốt. Vì vậy, tôi cố gắng tiếp tục:

> git rebase --continue
Applying: new version, new branch
No changes - did you forget to use 'git add'?

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

Đó là vào thời điểm này, sau khi nói đi nói lại chuyện này, tôi đập đầu vào bàn.

Những gì đang xảy ra ở đây? Tôi đang làm gì sai? Bất cứ ai có thể đặt tôi thẳng thắn?

EDIT - cho unutbu

Tôi đã thay đổi tệp như bạn đề xuất và gặp lỗi tương tự:

> git rebase master
First, rewinding head to replay your work on top of it...
Applying: new version, new branch
error: patch failed: app/views/common/version.txt:1
error: app/views/common/version.txt: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging app/views/common/version.txt
CONFLICT (content): Merge conflict in app/views/common/version.txt
Failed to merge in the changes.
Patch failed at 0001 new version, new branch

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

10
cảm ơn cho hỏi câu hỏi này .. tôi đã phải đối mặt với cùng một vấn đề chính xác
Archan Mishra

6
sẽ rất tốt nếu bạn xác nhận một số câu trả lời
holms

3
@MaxWilliams, tôi nghĩ bạn (cũng như tôi) đã hiểu sai lời khuyên của @unutbu : 1) trước tiên bạn chạy git rebase master và để nó thất bại ; 2) sau đó bạn chỉnh sửa version.txtvà làm cho nó giống như ở thời điểm đó, và lưu bản chỉnh sửa; 3) sau đó bạn git add .../version.txt; 4) sau đó bạn làm git rebase --continue( không phải 'cam kết' )! Nếu rebase --continuethành công ở đây, nó đã được cam kết (không cần git commitở đây!) - vì vậy tất cả những gì còn lại phải làm git push(nếu bạn sử dụng repo từ xa). Hy vọng điều này sẽ hữu ích, nếu tôi hiểu đúng :)- chúc mừng!
sdaau

@MaxWilliams, đã bao giờ bạn nhận được một câu trả lời cho điều này: ruby-forum.com/topic/187288 (Tôi sẽ nhanh chóng xóa này sau khi trả lời nếu ai đó không đạt được điều đó đầu tiên !!)
ATW

Câu trả lời:


102

Tôi gặp sự cố tương tự với rebase. Sự cố của tôi là do một trong các cam kết của tôi chỉ thay đổi một tệp và khi giải quyết, tôi đã hủy thay đổi được giới thiệu trong cam kết này. Tôi đã có thể giải quyết vấn đề của mình bằng cách bỏ qua cam kết tương ứng ( git rebase --skip).

Bạn có thể tái tạo vấn đề này trong một kho lưu trữ thử nghiệm. Đầu tiên hãy tạo kho lưu trữ.

$ mkdir failing-merge
$ cd failing-merge
$ git init
Initialized empty Git repository in $HOME/failing-merge/.git/

Sau đó, cam kết nội dung gốc của version.txttrong tổng thể.

$ echo v1.4-alpha-02 > version.txt
$ git add version.txt
$ git commit -m initial
[master (root-commit) 2eef0a5] initial
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 version.txt

Tạo v4nhánh và thay đổi nội dung của version.txt.

$ git checkout -b v4
Switched to a new branch 'v4'
$ echo v1.4-alpha-03 > version.txt
$ git add version.txt
$ git commit -m v4
[v4 1ef8c9b] v4
 1 files changed, 1 insertions(+), 1 deletions(-)

Quay lại mastervà thay đổi nội dung của version.txtđể sẽ có một conflit trong quá trình rebase.

$ git checkout master
Switched to branch 'master'
$ echo v1.4-alpha-04 > version.txt
$ git add version.txt
$ git commit -m master
[master 7313eb3] master
 1 files changed, 1 insertions(+), 1 deletions(-)

Chuyển trở lại v4nhánh và cố gắng căn cứ lại. Nó không thành công với một conflit trong version.txtnhư kế hoạch.

$ git checkout v4
Switched to branch 'v4'
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: v4
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging version.txt
CONFLICT (content): Merge conflict in version.txt
Recorded preimage for 'version.txt'
Failed to merge in the changes.
Patch failed at 0001 v4

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
$ cat version.txt
<<<<<<< HEAD
v1.4-alpha-04
=======
v1.4-alpha-03
>>>>>>> v4

Chúng tôi giải quyết xung đột bằng cách chọn masternội dung của version.txt. Chúng tôi thêm tệp và cố gắng tiếp tục rebase của chúng tôi.

$ echo v1.4-alpha-04 > version.txt
$ git add version.txt
$ git rebase --continue 
Applying: v4
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

Nó thất bại ! Hãy xem có những thay đổi nào gittrong kho lưu trữ của chúng tôi.

$ git status
# Not currently on any branch.
nothing to commit (working directory clean)

Ah ah, không có thay đổi. Nếu bạn đọc chi tiết thông báo lỗi trước đó, hãy gitthông báo cho chúng tôi về điều này và khuyến nghị sử dụng git rebase --skip. Anh ấy nói với chúng tôi "Nếu không còn gì để diễn ra, rất có thể một thứ khác đã đưa ra những thay đổi tương tự; bạn có thể muốn bỏ qua bản vá này." Vì vậy, chúng tôi chỉ cần bỏ qua cam kết và rebase thành công.

$ git rebase --skip
HEAD is now at 7313eb3 master

Lời cảnh báo : Xin lưu ý rằng điều đó git rebase --skipsẽ loại bỏ hoàn toàn cam kết gitđã cố gắng rebase. Trong trường hợp của chúng tôi, điều này sẽ ổn vì gitđang phàn nàn rằng đây là một cam kết trống. Nếu bạn cho rằng mình đã mất các thay đổi sau khi rebase hoàn tất, bạn có thể sử dụng git reflogđể lấy id cam kết của kho lưu trữ của mình trước rebase và sử dụng git reset --hardđể lấy lại kho của bạn ở trạng thái đó (đây là một thao tác phá hoại khác).


4
Cảm ơn vì đã dành thời gian viết lời giải thích dài dòng đó Sylvain! Điều đó làm cho nó rõ ràng hơn. Tôi nghĩ rằng tôi luôn lo lắng khi bỏ qua một bản vá vì có cảm giác như công việc có thể bị mất: tức là bản vá liên quan đến tất cả các tệp bị ảnh hưởng bởi rebase, thay vì chỉ một trong những xung đột. Sau đó, một bản vá chỉ là một hợp nhất duy nhất trên một tệp duy nhất?
Max Williams

3
Không, một bản vá chứa tất cả sự khác biệt trên tất cả các tệp được sửa đổi trong một cam kết duy nhất. Nhưng khi sử dụng git rebase --skip, bạn chỉ bỏ qua một lần commit duy nhất. Tôi thường đưa ra một git statustrước khi bỏ qua cam kết để xem liệu tôi có ở trong tình huống này hay không.
Sylvain Defresne

1
Tôi chỉ muốn nói với Max rằng cảm ơn vì đã dành thời gian viết ra một lời giải thích tuyệt vời — cuối cùng thì tôi cũng hiểu tại sao điều này lại xảy ra. Tôi cũng không còn sợ nữa rebase --skip:).
Ben Dolman

1
Cảnh báo - nếu bạn có nhiều thay đổi trong một lần cam kết, bạn có thể mất công thực hiện git rebase --skip. Tôi vừa làm
Chrissy H

@ChrissyH Trừ khi bạn đã làm một git reflog purgehoặc git reflog deletebạn vẫn có thể lấy lại các thay đổi của mình bằng cách sử dụng git reflog. Cố gắng kiểm tra các cam kết khác nhau được tham chiếu ở đó, một trong số chúng phải là trạng thái của cây của bạn trước khi bạn bắt đầu toàn bộ git rebase.
Sylvain Defresne

23

Trích dẫn từ đây: http://wholemeal.co.nz/node/9

Huh?!? Không, tôi không quên sử dụng git add, tôi đã làm điều đó ... như ... 2 giây trước!

Hóa ra là do không có thay đổi nào từ bản vá nên git nghi ngờ có điều gì đó không ổn. Git hy vọng một bản vá đã được áp dụng, nhưng tệp vẫn không thay đổi.

Thông báo lỗi không trực quan lắm, nhưng nó chứa câu trả lời. Chúng tôi chỉ cần yêu cầu rebase bỏ qua bản vá này. Cũng không cần thiết phải sửa các điểm đánh dấu xung đột trong tệp. Bạn sẽ kết thúc với phiên bản tệp từ nhánh mà bạn đang khôi phục.

$ git rebase --skip

Sau khi tôi sử dụng git mergetool và sửa các thay đổi, sau đó thêm chúng và cam kết chúng, tôi chỉ cần nhập <code> git rebase --skip </code> trong khi 'Hiện không có trong bất kỳ chi nhánh nào.' Và mọi thứ đã được sửa chữa. Cảm ơn!
geerlingguy

Trên thực tế, tôi nghĩ rằng đó là sự kết hợp của việc liên tục chạy git mergetool, sau đó git rebase --continue, sau đó git mergetool, v.v. cuối cùng đã khắc phục được tình trạng của tôi.
geerlingguy

6

Thông báo lỗi đó là kết quả của bạn git commit -a -m "merged". Nếu bạn chỉ cần sửa tệp, sau đó chạy git add <file>, và git rebase --continuenó sẽ hoạt động tốt. git rebase --continueđang cố gắng thực hiện một cam kết, nhưng nhận thấy rằng không có thay đổi nào đang chờ xử lý để cam kết (vì bạn đã cam kết chúng rồi).


1
Điều này có vẻ hợp lý hơn là bỏ qua, ít nhất là trong trường hợp chung. Tôi ngạc nhiên vì nó không được liệt kê là câu trả lời hay nhất.
Ngọc lục bảoD.

1
@EmeraldD., Không hoạt động. Sửa tệp và chạy git add <file>sẽ không giải quyết được sự cố. git rebase --continue vẫn báo cáoNo changes - did you forget to use 'git add'?
Pacerier

6

Thay đổi app / views / common / version.txt thành

v1.4-alpha-01

Tại thời điểm này trong rebase, hãy nhớ rằng bạn đang giải quyết xung đột hợp nhất để hiển thị tiến trình của nhánh không phải chính .

Vì vậy, trong việc phục hồi từ

      A---B---C topic
     /
D---E---F---G master

đến

              A*--B*--C* topic
             /
D---E---F---G master

xung đột mà bạn đang giải quyết nằm ở cách tạo A * trên nhánh chủ đề.

Vì vậy, sau khi thực hiện git rebase --abort, các lệnh sẽ

git checkout topic
git rebase master
< make edits to resolve conflicts >
git add .
git rebase --continue

3
Cảm ơn unutbu, tôi đã thử điều đó nhưng không may mắn: hãy xem OP để biết bản chỉnh sửa mới. cổ vũ
Max Williams

4

Hành vi bạn đang thấy không phải là những gì tôi mong đợi từ một rebase điển hình chỉ với xung đột này. Cân nhắc sử dụng một nhánh riêng để thực hiện việc rebase này (đặc biệt nếu bạn đã đẩy các cam kết từ xa mà bạn đang chuyển tiếp nhanh). Ngoài ra, git mergetoolcó thể hữu ích cho việc giải quyết xung đột và ghi nhớ vấn đề a git add.

Trong ví dụ tối thiểu này, rebase hoạt động như mong đợi. Bạn có thể cung cấp một ví dụ cho thấy hành vi bạn đang thấy không?

#!/bin/bash

cd /tmp
mkdir rebasetest
cd rebasetest
git init
echo 'v1.0' > version.txt
git add version.txt
git commit -m 'initial commit'
git checkout -b v4
echo 'v1.4-alpha-01' > version.txt
git add version.txt
git commit -m 'created v4'
git checkout master
git merge v4
echo 'v1.4-alpha-01-rc1' > version.txt
git add version.txt
git commit -m 'upped version on master to v1.4-alpha-01-rc1'
git checkout v4
echo 'v1.4-alpha-02' > version.txt
git add version.txt
git commit -m 'starting work on alpha-02'

git rebase master
echo 'v1.4-alpha-02' > version.txt
git add version.txt
git rebase --continue

4

Đây là một số ý tưởng:

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.