Từ các câu trả lời khác ở đây, tôi đã bối rối với cách git rebase -i
sử dụng để loại bỏ một cam kết, vì vậy tôi hy vọng sẽ ổn khi ghi lại trường hợp thử nghiệm của mình ở đây (rất giống với OP).
Đây là bash
tập lệnh mà bạn có thể dán vào để tạo kho lưu trữ kiểm tra trong /tmp
thư mục:
set -x
rm -rf /tmp/myrepo*
cd /tmp
mkdir myrepo_git
cd myrepo_git
git init
git config user.name me
git config user.email me@myself.com
mkdir folder
echo aaaa >> folder/file.txt
git add folder/file.txt
git commit -m "1st git commit"
echo bbbb >> folder/file.txt
git add folder/file.txt
git commit -m "2nd git commit"
echo cccc >> folder/file.txt
git add folder/file.txt
git commit -m "3rd git commit"
echo dddd >> folder/file.txt
git add folder/file.txt
git commit -m "4th git commit"
echo eeee >> folder/file.txt
git add folder/file.txt
git commit -m "5th git commit"
Tại thời điểm này, chúng tôi có một file.txt
với các nội dung sau:
aaaa
bbbb
cccc
dddd
eeee
Tại thời điểm này, CHÍNH nằm ở lần xác nhận thứ 5, ĐẦU ~ 1 sẽ là lần thứ 4 - và ĐẦU ~ 4 sẽ là lần cam kết thứ nhất (vì vậy, ĐẦU ~ 5 sẽ không tồn tại). Giả sử chúng tôi muốn xóa cam kết thứ 3 - chúng tôi có thể ban hành lệnh này trong myrepo_git
thư mục:
git rebase -i HEAD~4
( Lưu ý rằng git rebase -i HEAD~5
kết quả với. "Chết người: Cần một phiên bản duy nhất; không hợp lệ ĐẦU ~ 5 ngược dòng" ) Một soạn thảo văn bản (xem ảnh chụp màn hình trong câu trả lời @Dennis' ) sẽ mở ra với những nội dung:
pick 5978582 2nd git commit
pick 448c212 3rd git commit
pick b50213c 4th git commit
pick a9c8fa1 5th git commit
# Rebase b916e7f..a9c8fa1 onto b916e7f
# ...
Vì vậy, chúng tôi nhận được tất cả các cam kết kể từ (nhưng không bao gồm ) ĐẦU ~ 4 được yêu cầu của chúng tôi. Xóa dòng pick 448c212 3rd git commit
và lưu tệp; bạn sẽ nhận được phản hồi này từ git rebase
:
error: could not apply b50213c... 4th git commit
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".
Could not apply b50213c... 4th git commit
Tại thời điểm này, mở myrepo_git / folder/file.txt
trong trình soạn thảo văn bản; bạn sẽ thấy nó đã được sửa đổi:
aaaa
bbbb
<<<<<<< HEAD
=======
cccc
dddd
>>>>>>> b50213c... 4th git commit
Về cơ bản, git
thấy rằng khi ĐẦU đạt đến cam kết thứ 2, có nội dung của aaaa
+ bbbb
; và sau đó nó có một bản vá thêm cccc
+ dddd
mà nó không biết cách thêm vào nội dung hiện có.
Vì vậy, ở đây git
không thể quyết định cho bạn - chính bạn là người phải đưa ra quyết định: bằng cách xóa cam kết thứ 3, bạn có thể giữ các thay đổi được giới thiệu bởi nó (ở đây, dòng cccc
) - hoặc bạn không. Nếu bạn không, chỉ cần xóa các dòng bổ sung - bao gồm cccc
- trong folder/file.txt
việc sử dụng trình soạn thảo văn bản, để nó trông như thế này:
aaaa
bbbb
dddd
... và sau đó tiết kiệm folder/file.txt
. Bây giờ bạn có thể đưa ra các lệnh sau trong myrepo_git
thư mục:
$ nano folder/file.txt # text editor - edit, save
$ git rebase --continue
folder/file.txt: needs merge
You must edit all merge conflicts and then
mark them as resolved using git add
Ah - vì vậy để đánh dấu mà chúng tôi đã giải quyết được mâu thuẫn, chúng tôi phải git add
sự folder/file.txt
, trước khi thực hiện git rebase --continue
:
$ git add folder/file.txt
$ git rebase --continue
Ở đây, một trình soạn thảo văn bản sẽ mở lại, hiển thị dòng 4th git commit
- ở đây chúng ta có cơ hội thay đổi thông điệp cam kết (trong trường hợp này có thể được thay đổi một cách có ý nghĩa 4th (and removed 3rd) commit
hoặc tương tự). Giả sử bạn không muốn - vì vậy chỉ cần thoát trình soạn thảo văn bản mà không lưu; một khi bạn làm điều đó, bạn sẽ nhận được:
$ git rebase --continue
[detached HEAD b8275fc] 4th git commit
1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/master.
Tại thời điểm này, bây giờ bạn có một lịch sử như thế này (mà bạn cũng có thể kiểm tra bằng nói gitk .
hoặc các công cụ khác) về nội dung của folder/file.txt
(với, rõ ràng, dấu thời gian không thay đổi của các cam kết ban đầu):
1st git commit | +aaaa
----------------------------------------------
2nd git commit | aaaa
| +bbbb
----------------------------------------------
4th git commit | aaaa
| bbbb
| +dddd
----------------------------------------------
5th git commit | aaaa
| bbbb
| dddd
| +eeee
Và nếu trước đây, chúng tôi đã quyết định giữ dòng cccc
(nội dung của cam kết git thứ 3 mà chúng tôi đã xóa), chúng tôi sẽ có:
1st git commit | +aaaa
----------------------------------------------
2nd git commit | aaaa
| +bbbb
----------------------------------------------
4th git commit | aaaa
| bbbb
| +cccc
| +dddd
----------------------------------------------
5th git commit | aaaa
| bbbb
| cccc
| dddd
| +eeee
Chà, đây là kiểu đọc mà tôi hy vọng tôi đã tìm thấy, để bắt đầu tìm hiểu cách thức git rebase
hoạt động trong việc xóa các cam kết / sửa đổi; vì vậy hy vọng nó cũng có thể giúp đỡ người khác ...