git reset
là tất cả về di chuyển HEAD
, và nói chung là chi nhánh ref .
Câu hỏi: những gì về cây làm việc và chỉ số?
Khi làm việc với --soft
, di chuyển HEAD
, thường xuyên cập nhật các chi nhánh ref và chỉHEAD
.
Điều này khác commit --amend
với:
- nó không tạo ra một cam kết mới.
- nó thực sự có thể di chuyển CHÍNH đến bất kỳ cam kết nào (
commit --amend
chỉ là về việc không di chuyển CHÍNH, trong khi cho phép làm lại cam kết hiện tại)
Chỉ cần tìm ví dụ này về sự kết hợp:
- một sự hợp nhất cổ điển
- hợp nhất cây con
tất cả thành một (bạch tuộc, vì có nhiều hơn hai nhánh được hợp nhất) cam kết hợp nhất.
Tomas "wasroulette" Carnecky giải thích trong bài viết "Subtree Octopus merge" của mình :
- Chiến lược hợp nhất cây con có thể được sử dụng nếu bạn muốn hợp nhất một dự án vào thư mục con của dự án khác và sau đó giữ cho dự án con được cập nhật. Nó là một thay thế cho mô hình con git.
- Chiến lược hợp nhất bạch tuộc có thể được sử dụng để hợp nhất ba hoặc nhiều nhánh. Chiến lược bình thường chỉ có thể hợp nhất hai nhánh và nếu bạn cố gắng hợp nhất nhiều hơn thế, git sẽ tự động quay trở lại chiến lược bạch tuộc.
Vấn đề là bạn chỉ có thể chọn một chiến lược. Nhưng tôi muốn kết hợp cả hai để có được một lịch sử rõ ràng trong đó toàn bộ kho được cập nhật nguyên bản lên một phiên bản mới.
Tôi có một siêu projectA
dự án , hãy gọi nó và một tiểu dự án projectB
, mà tôi đã hợp nhất thành một thư mục con của projectA
.
(đó là phần hợp nhất của cây con)
Tôi cũng đang duy trì một vài cam kết địa phương.
ProjectA
được cập nhật thường xuyên, projectB
có phiên bản mới mỗi vài ngày hoặc vài tuần và thường phụ thuộc vào một phiên bản cụ thể của projectA
.
Khi tôi quyết định cập nhật cả hai dự án, tôi không chỉ đơn giản rút ra projectA
và projectB
vì điều đó sẽ tạo ra hai cam kết cho những gì nên là một bản cập nhật nguyên tử của toàn bộ dự án .
Thay vào đó, tôi tạo ra một hợp nhất cam kết duy nhất mà liên hợp gặt đập projectA
, projectB
và địa phương cam kết của tôi .
Phần khó khăn ở đây là đây là sự hợp nhất của bạch tuộc (ba đầu), nhưng projectB
cần phải được hợp nhất với chiến lược cây con . Vì vậy, đây là những gì tôi làm:
# Merge projectA with the default strategy:
git merge projectA/master
# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master
Ở đây, tác giả đã sử dụng một reset --hard
, và sau đó read-tree
để khôi phục lại hai lần hợp nhất đầu tiên đã thực hiện cho cây và chỉ mục, nhưng đó là nơi reset --soft
có thể giúp:
Làm thế nào để tôi làm lại hai sự hợp nhất đó, đã hoạt động, tức là cây và chỉ mục của tôi tốt, nhưng không phải ghi lại hai cam kết?
# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}
Bây giờ, chúng ta có thể tiếp tục giải pháp của Tomas:
# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
# And finally do the commit:
git commit
Vì vậy, mỗi lần:
- bạn hài lòng với những gì bạn kết thúc (về cây và chỉ số làm việc)
- bạn không hài lòng với tất cả các cam kết đưa bạn đến đó:
git reset --soft
là câu trả lời.
git reset --soft
: stackoverflow.com/questions/6869705/