Có phiên bản nào của họ không, phiên bản của họ có thể được sử dụng hay không?


876

Khi hợp nhất nhánh chủ đề "B" thành "A" bằng cách sử dụng git merge, tôi gặp một số xung đột. Tôi biết tất cả các xung đột có thể được giải quyết bằng phiên bản trong "B".

Tôi nhận thức được git merge -s ours. Nhưng những gì tôi muốn là một cái gì đó như git merge -s theirs.

Tại sao nó không tồn tại? Làm thế nào tôi có thể đạt được kết quả tương tự sau khi hợp nhất xung đột với các gitlệnh hiện có ? ( git checkoutmọi tệp không được trộn từ B)

CẬP NHẬT: "Giải pháp" chỉ loại bỏ bất cứ thứ gì từ nhánh A (điểm cam kết hợp nhất thành phiên bản B của cây) không phải là thứ tôi đang tìm kiếm.


1
Cũng xem câu trả lời này: stackoverflow.com/questions/928646/ trên - thay đổi ví dụ để sử dụng phiên bản B thay vì A.
Robie Basak

8
Xem SO trả lời lệnh git để tạo một nhánh giống như một nhánh khác cho tất cả các cách có thể hiện tại để mô phỏnggit merge -s their .
VonC

4
Vì vậy, bạn không thực sự tìm kiếm một git merge -s theirs(có thể dễ dàng đạt được git merge -s oursvà một chi nhánh tạm thời), vì - chúng ta hoàn toàn bỏ qua những thay đổi của chi nhánh hợp nhất ...
Nicolò Martini

21
@Torek - làm như Git devs thực sự thấy nó tấn công để cung cấp theirsthêm vào ours??? Đây là một triệu chứng của một trong những vấn đề kỹ thuật và thiết kế cấp cao trong Git: sự không nhất quán.
jww

3
@jww Vấn đề ở đây không phải là "git merge -s ours" gây khó chịu, mà là nó phản tác dụng. Bạn có thể thấy từ câu hỏi của OP rằng nếu một tính năng như vậy được thêm vào, anh ta sẽ sử dụng nó một cách nhầm lẫn khi điều anh ta thực sự muốn làm là "git merge -s đệ quy -X của họ". Thông thường muốn hợp nhất một chi nhánh khác ghi đè xung đột với phiên bản trên nhánh khác, nhưng việc ghi đè hoàn toàn chi nhánh hiện tại bằng một chi nhánh khác hoàn toàn loại bỏ các thay đổi hiện tại là một trường hợp ngoại lệ.
ThomazMoura

Câu trả lời:


1019

Thêm -Xtùy chọn vào theirs. Ví dụ:

git checkout branchA
git merge -X theirs branchB

Mọi thứ sẽ hợp nhất theo cách mong muốn.

Điều duy nhất tôi thấy có vấn đề là nếu các tệp bị xóa khỏi nhánhB. Chúng hiển thị như xung đột nếu một cái gì đó khác ngoài git đã loại bỏ.

Việc khắc phục rất dễ dàng. Chỉ cần chạy git rmvới tên của bất kỳ tập tin đã bị xóa:

git rm {DELETED-FILE-NAME}

Sau đó, -X theirsnên làm việc như mong đợi.

Tất nhiên, thực hiện loại bỏ thực tế bằng git rmlệnh sẽ ngăn xung đột xảy ra ngay từ đầu.


Lưu ý : Một tùy chọn hình thức dài hơn cũng tồn tại.

Để sử dụng nó, thay thế:

-X theirs

với:

--strategy-option=theirs

6
Xem câu trả lời khác dưới đây để có giải pháp tốt hơn (Paul Pladijs) cho câu hỏi ban đầu.
Malcolm

204
Đáng lưu ý rằng điều này không giống như "chiến lược hợp nhất theirs". -Xtheirs là tùy chọn chiến lược được áp dụng cho chiến lược đệ quy . Điều này có nghĩa là chiến lược đệ quy vẫn sẽ hợp nhất bất cứ điều gì có thể, và sẽ chỉ quay lại logic "của họ" trong trường hợp có xung đột. Mặc dù đây là những gì người ta cần trong hầu hết các trường hợp như trên, nhưng điều này không giống như "chỉ cần lấy mọi thứ từ nhánh B". Nó thực sự hợp nhất thay vì dù sao.
Timur

2
Nó hoạt động với các lệnh khác là tốt. Tôi vừa mới làm một 'git cherry-pick sha1 -X của họ'. Cảm ơn!
Max Hohenegger

48
Đây là một câu trả lời khủng khiếp, bởi vì nó có vẻ đúng, nhưng thực sự là sai. "Git merge -X của họ" không làm những gì "git merge -s của họ" sẽ làm. Nó không thay thế chi nhánh hiện tại bằng nội dung của chi nhánh được sáp nhập. Nó thích thay đổi "của họ", nhưng chỉ trong trường hợp có xung đột. Do đó, cam kết kết quả có thể khác hoàn toàn với nhánh "của họ". Đây không phải là những gì các poster câu hỏi có trong tâm trí.
Ivan Krivyakov

7
@ user3338098: đúng, bạn đúng. Tôi đọc lại câu hỏi, và nó cũng không tốt lắm. Thật không may, nguyên nhân sâu xa của sự nhầm lẫn không phải là câu trả lời và thậm chí không phải là câu hỏi. Đây là lựa chọn thiết kế của các tác giả git để đặt cùng tên 'chúng ta' cho một chiến lược hợp nhất và cho một tùy chọn của chiến lược hợp nhất 'đệ quy'. Sự nhầm lẫn trong trường hợp này là thực tế không thể tránh khỏi.
Ivan Krivyakov

218

Một giải pháp khả thi và đã được thử nghiệm để sáp nhập chi nhánhB vào chi nhánh đã thanh toán của chúng tôiA:

# in case branchA is not our current branch
git checkout branchA

# make merge commit but without conflicts!!
# the contents of 'ours' will be discarded later
git merge -s ours branchB    

# make temporary branch to merged commit
git branch branchTEMP         

# get contents of working tree and index to the one of branchB
git reset --hard branchB

# reset to our merged commit but 
# keep contents of working tree and index
git reset --soft branchTEMP

# change the contents of the merged commit
# with the contents of branchB
git commit --amend

# get rid off our temporary branch
git branch -D branchTEMP

# verify that the merge commit contains only contents of branchB
git diff HEAD branchB

Để tự động hóa nó, bạn có thể gói nó thành một tập lệnh bằng cách sử dụng BranchA và BranchB làm đối số.

Giải pháp này bảo tồn cha mẹ thứ nhất và thứ hai của cam kết hợp nhất, như bạn mong đợi git merge -s theirs branchB.


Q: Tại sao bạn cần BranchTEMP? Có phải bạn git reset --soft branchAkhông?
cdunn2001

4
@ cdunn2001: Bằng cách nào đó tôi đã nghĩ điều tương tự, nhưng không. Lưu ý rằng git reset --hardnhững thay đổi mà cam kết branchAđiểm.
Tsuyoshi Ito

5
xin lỗi để hỏi một câu hỏi ngu ngốc nhưng tại sao phương pháp này tốt hơn các -xtheirs? những lợi thế / bất lợi là gì
chrispepper1989

9
@ chrispepper1989 -x của họ chỉ ảnh hưởng đến xung đột , nếu một khối của chúng ta có thể được áp dụng sạch sẽ, nó sẽ thông qua kết hợp hợp nhất. Trong trường hợp này, như được hiển thị bởi lệnh cuối cùng, chúng ta sẽ nhận được một sự hợp nhất hoàn toàn giống với nhánhB, bất kể có xảy ra xung đột hay không.
ChúZeiv

2
@UncleZeiv cảm ơn bạn đã giải thích, vì vậy về cơ bản, việc thực hiện "của họ" sẽ giữ các thay đổi và tệp không bị xung đột dẫn đến mã int không giống với mã đã kéo.
chrispepper1989

89

Các phiên bản cũ hơn của git cho phép bạn sử dụng chiến lược hợp nhất "của họ":

git pull --strategy=theirs remote_branch

Nhưng điều này đã bị xóa, như được giải thích trong tin nhắn này của Junio ​​Hamano (người duy trì Git). Như đã lưu ý trong liên kết, thay vào đó bạn sẽ làm điều này:

git fetch origin
git reset --hard origin

Mặc dù vậy, hãy coi chừng rằng điều này khác với hợp nhất thực tế. Giải pháp của bạn có lẽ là lựa chọn bạn thực sự tìm kiếm.


7
Tôi thực sự không hiểu lời giải thích của Junio ​​Hamano. Làm thế nào là git reset --hard originmột giải pháp cho một phong cách hợp nhất của họ? Nếu tôi muốn hợp nhất BranchB vào BranchA (như trong câu trả lời của Alan W. Smith), tôi sẽ làm thế nào bằng resetphương pháp này?
James McMahon

3
@James McMahon: Quan điểm của Junio ​​C Hamano không phải là git reset --hardsự hợp nhất theo kiểu của họ. Tất nhiên, git reset --hardkhông tạo ra bất kỳ cam kết hợp nhất, hoặc bất kỳ cam kết nào cho vấn đề đó. Quan điểm của ông là chúng ta không nên sử dụng một sự hợp nhất để thay thế bất cứ thứ gì trong ĐẦU bằng một thứ khác. Tôi không nhất thiết phải đồng ý, mặc dù.
Tsuyoshi Ito

11
Đó là một sự xấu hổ rằng theirsđã được gỡ bỏ vì lý do không đầy đủ. Không thể cho phép những trường hợp mã tốt, chỉ là dòng ngược được duy trì trên cơ sở triết học khác, vì vậy theo nghĩa đó là 'xấu', vì vậy người ta không muốn cập nhật thông tin ngược dòng, nhưng đồng thời giữ lại những mã tốt 'sửa lỗi' [git & msysgit có một số 'xung đột' này vì triết lý nền tảng mục tiêu khác nhau của họ]
Philip Oakley

1
Nó cũng thiếu trường hợp sử dụng mà tôi đang mắc kẹt ngay bây giờ, nơi tôi đang chia sẻ một chi nhánh với người khác và cả hai chúng tôi đã tình cờ đẩy mạnh các thay đổi (trên các tệp khác nhau) cùng một lúc. Vì vậy, tôi muốn ghi đè tất cả các phiên bản cũ mà tôi có tại địa phương và sử dụng phiên bản mới hơn của anh ấy. Anh ấy muốn làm tương tự cho các tập tin tôi cập nhật. Không có gì để 'thiết lập lại'. Và giải pháp kiểm tra từng tệp riêng lẻ là không thực tế khi nó ~ 20 tệp.
szeitlin

2
Tôi thực sự không hiểu triết lý. Tôi chỉ sử dụng theirsvì tôi đã vô tình thay đổi một số tệp trong hai nhánh riêng biệt và muốn loại bỏ các thay đổi của một tệp mà không phải thực hiện thủ công cho mỗi tệp.
sudo

65

Nó không hoàn toàn rõ ràng kết quả mong muốn của bạn là gì, vì vậy có một số nhầm lẫn về cách làm "chính xác" trong câu trả lời và nhận xét của họ. Tôi cố gắng đưa ra một cái nhìn tổng quan và xem ba tùy chọn sau:

Hãy thử hợp nhất và sử dụng B cho các xung đột

Đây không phải là "phiên bản của họ cho git merge -s ours" mà là "phiên bản của họ cho git merge -X ours" (viết tắt của git merge -s recursive -X ours):

git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB

Đây là những gì ví dụ câu trả lời của Alan W. Smith .

Chỉ sử dụng nội dung từ B

Điều này tạo ra một cam kết hợp nhất cho cả hai nhánh nhưng loại bỏ tất cả các thay đổi từ branchAvà chỉ giữ nội dung từ đó branchB.

# Get the content you want to keep.
# If you want to keep branchB at the current commit, you can add --detached,
# else it will be advanced to the merge commit in the next step.
git checkout branchB

# Do the merge an keep current (our) content from branchB we just checked out.
git merge -s ours branchA

# Set branchA to current commit and check it out.
git checkout -B branchA

Lưu ý rằng hợp nhất cam kết cha mẹ đầu tiên bây giờ là từ branchBvà chỉ thứ hai là từ branchA. Đây là những gì ví dụ như câu trả lời của Gandalf458 .

Chỉ sử dụng nội dung từ B và giữ đúng thứ tự cha mẹ

Đây là "phiên bản của họ" thực sự git merge -s ours. Nó có cùng nội dung như trong tùy chọn trước đó (nghĩa là chỉ từ branchB) nhưng thứ tự của cha mẹ là chính xác, tức là cha mẹ đầu tiên đến từ branchAvà thứ hai từ branchB.

git checkout branchA

# Do a merge commit. The content of this commit does not matter,
# so use a strategy that never fails.
# Note: This advances branchA.
git merge -s ours branchB

# Change working tree and index to desired content.
# --detach ensures branchB will not move when doing the reset in the next step.
git checkout --detach branchB

# Move HEAD to branchA without changing contents of working tree and index.
git reset --soft branchA

# 'attach' HEAD to branchA.
# This ensures branchA will move when doing 'commit --amend'.
git checkout branchA

# Change content of merge commit to current index (i.e. content of branchB).
git commit --amend -C HEAD

Đây là những gì câu trả lời của Paul Pladijs (không yêu cầu một chi nhánh tạm thời).


Một phiên bản sạch của tùy chọn 3:git checkout branchA; git merge -s ours --no-commit branchB; git read-tree -um @ branchB; git commit
jthill

@jthill: Mặc dù phiên bản của bạn ngắn gọn hơn nhưng nó cũng sử dụng lệnh cấp thấp ("ống nước") read-treemà người dùng git trung bình có thể không được sử dụng (ít nhất là tôi không ;-)). Các giải pháp trong câu trả lời chỉ sử dụng các lệnh cấp cao ("sứ") mà hầu hết người dùng git nên biết. Tôi thích chúng nhưng cảm ơn bạn cho phiên bản của bạn tuy nhiên!
siegi

Bạn có thể giải thích bước thứ hai đến bước cuối cùng (chi nhánh thanh toánA) không? Có vẻ như nó không nên ở đó.
Patrick

@Patrick, bước này là bắt buộc. Nếu bạn bỏ qua nó, bạn sẽ nhận được cùng một cam kết nhưng bạn sẽ không có một nhánh chỉ vào cam kết này. Vì vậy, ngay khi bạn chuyển sang một cam kết / chi nhánh khác, cam kết bạn đã thực hiện với lệnh cuối cùng ( …commit --amend…) sẽ bị "mất". Tôi dự định thêm một số giải thích đồ họa vào câu trả lời này ngay khi tôi có thời gian để thực hiện chúng
;;)

62

Tôi đã sử dụng câu trả lời từ Paul Pladijs kể từ bây giờ. Tôi phát hiện ra, bạn có thể thực hiện hợp nhất "bình thường", xung đột xảy ra, vì vậy bạn làm

git checkout --theirs <file>

để giải quyết xung đột bằng cách sử dụng bản sửa đổi từ chi nhánh khác. Nếu bạn làm điều này cho mỗi tệp, bạn có hành vi giống như bạn mong đợi từ

git merge <branch> -s theirs

Dù sao, nỗ lực là nhiều hơn so với chiến lược hợp nhất! (Điều này đã được thử nghiệm với phiên bản git 1.8.0)


1
sẽ là tuyệt vời nếu danh sách các tập tin có thể được lấy. Ví dụ: git ls-files --modified | xargs git addtôi muốn làm điều này để thêm vào cả hai bên hợp nhất: /
andho

Trên thực tế git trả về các tệp được thêm vào trên cả hai mặt git ls-files --modifiedvì vậy tôi đoán đây cũng là một giải pháp khả thi.
andho

1
Cảm ơn vì đã thêm điều này. Thường thì không cần thiết trên cơ sở từng tệp. Ngoài ra, trạng thái git hiển thị "Đường dẫn không được trộn" ở dưới cùng. Để có được danh sách các đường dẫn chưa được giải quyết, tôi sử dụng bí danh này:git config --global alias.unresolved '!git status --short|egrep "^([DAU])\1"'
Melvyn

ý nghĩa của -Xvà sự khác biệt giữa -Xvà là -sgì? không thể tìm thấy bất kỳ tài liệu.
Lôi Dương

21

Tôi đã giải quyết vấn đề của mình bằng cách sử dụng

git checkout -m old
git checkout -b new B
git merge -s ours old

một nhánh "B" từ nhánh "cũ"
elmarco

13

Khi hợp nhất nhánh chủ đề "B" trong "A" bằng cách sử dụng git merge, tôi gặp một số xung đột. Tôi> biết tất cả các xung đột có thể được giải quyết bằng phiên bản trong "B".

Tôi nhận thức được git merge -s của chúng tôi. Nhưng những gì tôi muốn là một cái gì đó như git merge> -s của họ.

Tôi giả sử rằng bạn đã tạo một nhánh của chủ và bây giờ muốn hợp nhất trở lại thành chủ, ghi đè lên bất kỳ nội dung cũ nào trong chủ. Đó chính xác là những gì tôi muốn làm khi tôi đi qua bài viết này.

Làm chính xác những gì bạn muốn làm, ngoại trừ hợp nhất một nhánh vào nhánh khác trước. Tôi chỉ làm điều này, và nó đã làm việc tuyệt vời.

git checkout Branch
git merge master -s ours

Sau đó, kiểm tra tổng thể và hợp nhất chi nhánh của bạn trong đó (nó sẽ diễn ra suôn sẻ ngay bây giờ):

git checkout master
git merge Branch

1
Cảm ơn. Đây phải là câu trả lời được chấp nhận, cho đến nay là đơn giản nhất và chính xác nhất. Nếu chi nhánh của bạn đứng sau / xung đột với chủ, thì công việc chi nhánh của nó sẽ hợp nhất và làm cho mọi thứ hoạt động trước khi hợp nhất lại mọi thứ để làm chủ.
StackHola

Điều này làm việc tuyệt vời, cảm ơn bạn.
Kodie Grantham

12

Nếu bạn ở chi nhánh A, hãy làm:

git merge -s recursive -X theirs B

Đã thử nghiệm trên phiên bản git 1.7.8


8

Để thực sự hợp nhất, chỉ lấy đầu vào từ nhánh bạn đang hợp nhất, bạn có thể thực hiện

git merge --strategy=ours ref-to-be-merged

git diff --binary ref-to-be-merged | git apply --reverse --index

git commit --amend

Sẽ không có xung đột trong bất kỳ kịch bản nào tôi biết, bạn không phải tạo thêm các nhánh và nó hoạt động như một cam kết hợp nhất thông thường.

Điều này không chơi tốt với mô hình con tuy nhiên.


-R làm gì ở đây?
P. Myer Nore

Bằng cách này, bạn sẽ mất lịch sử của các tập tin "di chuyển và thay đổi". Tôi có đúng không
elysch

1
-R là --reverse, tôi đã cập nhật câu trả lời để có nhiều tài liệu hơn.
Elijah Lynn

Điều này dường như không hoạt động nếu các tệp bạn đang cố gắng hợp nhất bị xóa trong nhánh đến.
giải quyết

7

Tại sao nó không tồn tại?

Trong khi tôi đề cập đến trong " lệnh git để tạo một nhánh giống như một nhánh khác " git merge -s theirs, hãy lưu ý rằng Git 2.15 (Q4 2017) hiện rõ ràng hơn:

Tài liệu về ' -X<option>' cho các sự hợp nhất đã được viết sai để đề xuất rằng " -s theirs" tồn tại, đó không phải là trường hợp.

Xem cam kết c25d98b (ngày 25 tháng 9 năm 2017) của Junio ​​C Hamano ( gitster) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 4da3e23 , ngày 28 tháng 9 năm 2017)

chiến lược hợp nhất: tránh ngụ ý rằng " -s theirs" tồn tại

Mô tả về -Xourstùy chọn hợp nhất có một ghi chú chính xác cho độc giả biết rằng nó rất khác so -s oursvới chính xác, nhưng mô tả về -Xtheirsnó theo sau nó vô tư nói "điều này ngược lại ours", tạo ấn tượng sai mà người đọc cũng cần được cảnh báo rằng nó rất khác với-s theirs , trong thực tế thậm chí không tồn tại.

-Xtheirslà một lựa chọn chiến lược được áp dụng cho chiến lược đệ quy. Điều này có nghĩa là chiến lược đệ quy vẫn sẽ hợp nhất mọi thứ có thể và sẽ chỉ quay lại theirslogic "" trong trường hợp có xung đột.

Cuộc tranh luận về sự liên quan hay không của một theirschiến lược hợp nhất đã được đưa trở lại gần đây trong chủ đề tháng 9 năm 2017 này .
Nó thừa nhận chủ đề cũ hơn (2008)

Nói tóm lại, cuộc thảo luận trước đây có thể được tóm tắt thành "chúng tôi không muốn -s theirs" vì nó khuyến khích quy trình làm việc sai ".

Nó đề cập đến bí danh:

mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -

Yaroslav Halchenko cố gắng ủng hộ một lần nữa cho chiến lược đó, nhưng Junio ​​C. Hamano nói thêm :

Lý do tại sao chúng ta và của họ không đối xứng là vì bạn là bạn chứ không phải họ --- sự kiểm soát và quyền sở hữu lịch sử của chúng tôi và lịch sử của họ không đối xứng.

Khi bạn quyết định rằng lịch sử của họ là dòng chính, bạn muốn coi dòng phát triển của mình là nhánh phụ và hợp nhất theo hướng đó, tức là cha mẹ đầu tiên của hợp nhất kết quả là một cam kết về lịch sử của họ và thứ hai cha mẹ là người xấu cuối cùng trong lịch sử của bạn. Vì vậy, bạn sẽ kết thúc bằng cách sử dụng "checkout their-history && merge -s ours your-history " để giữ cho việc làm cha mẹ đầu tiên hợp lý.

Và tại thời điểm đó, việc sử dụng " -s ours" không còn là cách giải quyết cho việc thiếu " -s theirs".
Nó là một phần thích hợp của ngữ nghĩa mong muốn, tức là từ quan điểm của dòng lịch sử kinh điển còn sót lại, bạn muốn bảo tồn những gì nó đã làm, vô hiệu hóa những gì dòng khác của lịch sử đã làm .

Junio ​​cho biết thêm, như nhận xét của Mike Beaton :

git merge -s ours <their-ref>nói một cách hiệu quả, "các cam kết được tạo ra <their-ref>trên chi nhánh của họ là các cam kết sẽ bị bỏ qua vĩnh viễn";
và điều này quan trọng bởi vì, nếu sau đó bạn hợp nhất từ ​​các tiểu bang sau này của chi nhánh của họ, những thay đổi sau này sẽ được đưa vào mà không có những thay đổi bị bỏ qua từng được đưa vào .


1
Đây là một câu trả lời hữu ích, nhưng nó không đề cập đến một điểm quan trọng mà tôi vừa hiểu từ câu trả lời của Junio ​​C. Hamano: git merge -s ours <their-ref>nói một cách hiệu quả 'dấu cam kết được tạo ra cho <họ-ref> trên chi nhánh của họ vì cam kết bị bỏ qua vĩnh viễn '; và điều này quan trọng bởi vì, nếu sau đó bạn hợp nhất từ ​​các tiểu bang sau này của chi nhánh của họ, những thay đổi sau này sẽ được đưa vào mà không có thay đổi bị bỏ qua từng được đưa vào.
MikeBeaton

1
@MikeBeaton Cảm ơn bạn. Tôi đã bao gồm nhận xét của bạn trong câu trả lời để dễ nhìn hơn.
VonC

5

Xem câu trả lời được trích dẫn rộng rãi của Junio ​​Hamano : nếu bạn sẽ loại bỏ nội dung đã cam kết, chỉ cần loại bỏ các cam kết hoặc bằng bất cứ giá nào, hãy để nó ra khỏi lịch sử chính. Tại sao mọi người trong tương lai đọc các thông điệp cam kết từ các cam kết không có gì để cung cấp?

Nhưng đôi khi có những yêu cầu hành chính, hoặc có lẽ một số lý do khác. Đối với những tình huống mà bạn thực sự phải ghi lại các cam kết không đóng góp gì, bạn muốn:

(chỉnh sửa: wow, tôi đã quản lý để có được lỗi này trước đây. Cái này hoạt động.)

git update-ref HEAD $(
        git commit-tree -m 'completely superseding with branchB content' \
                        -p HEAD -p branchB    branchB:
)
git reset --hard

3

Cái này sử dụng lệnh đọc cây git, nhưng làm cho tổng thể công việc ngắn hơn.

git checkout <base-branch>

git merge --no-commit -s ours <their-branch>
git read-tree -u --reset <their-branch>
git commit

# Check your work!
git diff <their-branch>

0

Điều này sẽ hợp nhất newBranch của bạn trong baseBranch hiện có

git checkout <baseBranch> // this will checkout baseBranch
git merge -s ours <newBranch> // this will simple merge newBranch in baseBranch
git rm -rf . // this will remove all non references files from baseBranch (deleted in newBranch)
git checkout newBranch -- . //this will replace all conflicted files in baseBranch

Tôi khuyên bạn nên thêm git commit --amendvào cuối ví dụ của mình hoặc người dùng có thể thấy cam kết hợp nhất với git logvà giả sử thao tác đã hoàn tất.
Michael R

0

Tôi nghĩ những gì bạn thực sự muốn là:

git checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch

Điều này có vẻ vụng về, nhưng nó nên làm việc. Suy nghĩ duy nhất tôi thực sự không thích về giải pháp này là lịch sử git sẽ gây nhầm lẫn ... Nhưng ít nhất lịch sử sẽ được bảo tồn hoàn toàn và bạn sẽ không cần phải làm gì đặc biệt cho các tệp bị xóa.


0

Tương đương (giữ trật tự cha mẹ) để 'git merge -s nhánh của họB'

Trước khi hợp nhất:nhập mô tả hình ảnh ở đây

!!! Hãy chắc chắn rằng bạn đang ở trong trạng thái sạch sẽ !!!

Thực hiện hợp nhất:

git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command

Những gì chúng ta đã làm ? Chúng tôi đã tạo một cam kết mới mà hai cha mẹ của chúng tôi và của họ và mạng lưới của cam kết là chi nhánhB - của họ

Sau khi hợp nhất:nhập mô tả hình ảnh ở đây

Chính xác hơn:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'

0

Câu trả lời này được đưa ra bởi Paul Pladijs. Tôi chỉ nhận lệnh của anh ấy và tạo một bí danh git cho thuận tiện.

Chỉnh sửa .gitconfig của bạn và thêm vào như sau:

[alias]
    mergetheirs = "!git merge -s ours \"$1\" && git branch temp_THEIRS && git reset --hard \"$1\" && git reset --soft temp_THEIRS && git commit --amend && git branch -D temp_THEIRS"

Sau đó, bạn có thể "git merge -s thems A" bằng cách chạy:

git checkout B (optional, just making sure we're on branch B)
git mergetheirs A

-1

Gần đây tôi chỉ cần làm điều này cho hai kho riêng biệt có chung lịch sử. Tôi bắt đầu với:

  • Org/repository1 master
  • Org/repository2 master

Tôi muốn tất cả các thay đổi repository2 masterđược áp dụng repository1 master, chấp nhận tất cả các thay đổi mà repository2 sẽ thực hiện. Theo thuật ngữ của git, đây phải là một chiến lược gọi là -s theirsNHƯNG nó không tồn tại. Hãy cẩn thận vì -X theirsđược đặt tên như nó sẽ là những gì bạn muốn, nhưng nó không giống nhau (thậm chí nó còn nói như vậy trong trang man).

Cách tôi giải quyết điều này là đi đến repository2và tạo một chi nhánh mới repo1-merge. Trong chi nhánh đó, tôi đã chạy git pull git@gitlab.com:Org/repository1 -s oursvà nó hợp nhất không có vấn đề gì. Sau đó tôi đẩy nó ra xa.

Sau đó tôi trở lại repository1và làm một chi nhánh mới repo2-merge. Trong nhánh đó, tôi chạy git pull git@gitlab.com:Org/repository2 repo1-mergesẽ hoàn thành với các vấn đề.

Cuối cùng, bạn sẽ cần phải đưa ra một yêu cầu hợp nhất repository1để biến nó thành chủ mới, hoặc chỉ giữ nó như một nhánh.


-2

Một cách đơn giản và trực quan (theo tôi) cách làm hai bước là

git checkout branchB .
git commit -m "Picked up the content from branchB"

theo dõi bởi

git merge -s ours branchB

(đánh dấu hai nhánh là hợp nhất)

Nhược điểm duy nhất là nó không xóa các tệp đã bị xóa trong nhánhB khỏi nhánh hiện tại của bạn. Một khác biệt đơn giản giữa hai nhánh sau đó sẽ hiển thị nếu có bất kỳ tệp nào như vậy.

Cách tiếp cận này cũng làm cho nó rõ ràng từ nhật ký sửa đổi sau đó những gì đã được thực hiện - và những gì đã được dự định.


điều này có thể đúng cho câu hỏi ban đầu, tuy nhiên OP đã cập nhật câu hỏi vào năm 2008 theo cách mà câu trả lời này không chính xác.
dùng3338098

1
@ user3338098 Vâng, thật đáng tiếc khi họ để lại tiêu đề sai lệch và chỉ tát một bản cập nhật không rõ ràng ở phần cuối của câu hỏi .... bởi vì câu trả lời này trả lời đúng câu hỏi tiêu đề.
RomainValeri

Tôi hoàn toàn đồng ý với @RomainValeri
AppleCiderGuy
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.