Câu hỏi Đặt nhánh Git hiện tại thành nhánh chính


Tôi có một kho lưu trữ trong Git. Tôi đã làm một chi nhánh, sau đó đã thực hiện một số thay đổi cho cả chủ và chi nhánh.

Sau đó, hàng chục cam kết sau đó, tôi nhận ra rằng nhánh đang ở trạng thái tốt hơn nhiều so với bậc thầy, vì vậy tôi muốn nhánh cây "trở thành" thầy và bỏ qua những thay đổi trên thầy.

Tôi không thể hợp nhất nó, bởi vì tôi không muốn giữ các thay đổi trên master. Tôi nên làm gì?

Thêm: Trong trường hợp này, chủ nhân 'cũ' đã được pushđến một kho lưu trữ khác như GitHub. Làm thế nào điều này thay đổi mọi thứ?


1312
2018-05-04 05:30


gốc


Kiểm tra câu trả lời cho câu hỏi tương tự stackoverflow.com/q/2862590/151641 - mloskot
Đã có một vấn đề tương tự, tuy nhiên tôi chỉ cần loại bỏ chủ và đổi tên thành một nhánh khác để làm chủ: stackoverflow.com/a/14518201/189673 - jayarjo
@ jayarjo bạn nên tránh điều này nếu bạn có thể có thể bởi vì nó sẽ viết lại lịch sử và gây ra vấn đề cho mọi người khác khi họ tiếp theo cố gắng để kéo tổng thể. - joelittlejohn
Đây là lý do tại sao tôi yêu câu trả lời của @Jefromi. Không có sự phá hủy lịch sử của kho lưu trữ đang diễn ra. - froggythefrog


Các câu trả lời:


Vấn đề với hai câu trả lời còn lại là vị thầy mới không có thầy già làm tổ tiên, nên khi bạn đẩy nó, mọi người khác sẽ bị rối tung lên. Đây là những gì bạn muốn làm:

git checkout better_branch
git merge --strategy=ours master    # keep the content of this branch, but record a merge
git checkout master
git merge better_branch             # fast-forward master up to the merge

Nếu bạn muốn lịch sử của mình trở nên rõ ràng hơn một chút, tôi khuyên bạn nên thêm một số thông tin vào thư cam kết hợp nhất để làm rõ thông tin bạn đã làm. Thay đổi dòng thứ hai thành:

git merge --strategy=ours --no-commit master
git commit          # add information to the template merge message

1745
2018-05-04 06:00



Lưu ý về việc hợp nhất "chiến lược" của git: --strategy=ours la khac nhau tư --strategy=recursive -Xours. I E. "chúng ta" có thể là một chiến lược (kết quả sẽ là nhánh hiện tại không có vấn đề gì), hoặc được chuyển thành một tùy chọn cho chiến lược "đệ quy" (mang lại các thay đổi của chi nhánh khác và tự động thích thay đổi của nhánh hiện tại khi có xung đột) . - Kelvin
Tôi phải thực hiện dòng thứ hai git merge --strategy=ours master -m "new master" để nó hoạt động. - incandescentman
@Johsm Đó chính là câu đầu tiên của câu trả lời của tôi. Nếu bạn làm điều đó, tổng thể mới sẽ không có cùng một lịch sử như là bậc thầy cũ, mà là rất xấu nếu bạn muốn đẩy / kéo. Bạn cần phải có tổ tiên chia sẻ cho rằng để làm việc một cách chính xác; nếu thay vào đó bạn làm những gì bạn nói, thì khi bạn cố gắng đẩy nó sẽ đơn giản thất bại trừ khi bạn ép nó (vì điều này là Xấu và nó đang cố ngăn bạn), và nếu bạn ép nó, thì bất cứ ai sau đó sẽ kéo sẽ cố gắng để hợp nhất các bậc thầy cũ và chủ mới, mà có lẽ sẽ là một xác tàu. - Cascabel
Nếu trình soạn thảo vi trong quá trình hợp nhất xuất hiện, hãy gõ: w (để lưu): q (để thoát khỏi vi) - qub1n
Câu trả lời này hoạt động rất tốt. Tôi chỉ muốn thêm (đối với những người có thể mới hoặc không chắc chắn) mà bạn sẽ phải làm git push ngay sau này nếu bạn muốn mã của bạn được đẩy lên từ xa. Bạn có thể thấy cảnh báo như Your branch is ahead of 'origin/master' by 50 commits. Điều này được mong đợi. Chỉ cần đẩy nó! : D - chapeljuice


Đảm bảo mọi thứ được đẩy lên kho lưu trữ từ xa của bạn (GitHub):

git checkout master

Ghi đè "chính" bằng "better_branch":

git reset --hard better_branch

Buộc đẩy vào kho lưu trữ từ xa của bạn:

git push -f origin master

170
2018-06-24 20:25



Đây có lẽ là câu trả lời mà hầu hết mọi người đang tìm kiếm. Tất cả các câu trả lời khác với hợp nhất chiến lược BS không thay thế toàn bộ nhánh. Điều này làm mọi thứ giống như tôi muốn, chỉ cần ghi đè lên nhánh và đẩy nó lên. - Gubatron
mặc dù đây thực sự là điều mà nhiều người đang tìm kiếm, cần lưu ý rằng bất kỳ bản sao cục bộ nào của repo sẽ cần phải git reset --hard origin/master thời gian tới họ muốn kéo, git khác sẽ cố gắng hợp nhất các thay đổi vào (giờ địa phương khác nhau) khác nhau của họ. Những nguy hiểm của điều này được giải thích thêm trong câu trả lời này - 7yl4r
đồng ý! Đây là câu trả lời mà hầu hết mọi người đang tìm kiếm. - Antuan
cũng xin lưu ý rằng bạn cần được phép đẩy đẩy vào kho lưu trữ - ví dụ: trong môi trường kinh doanh, điều này sẽ không hoạt động - inetphantom


Chỉnh sửa: Bạn đã không nói rằng bạn đã đẩy đến một repo công cộng! Điều đó tạo nên một thế giới khác biệt.

Có hai cách, cách "bẩn" và cách "sạch". Giả sử chi nhánh của bạn được đặt tên new-master. Đây là cách sạch sẽ:

git checkout new-master
git branch -m master old-master
git branch -m new-master master
# And don't do this part.  Just don't.  But if you want to...
# git branch -d --force old-master

Điều này sẽ làm cho các tập tin cấu hình thay đổi để phù hợp với các chi nhánh được đổi tên.

Bạn cũng có thể làm điều đó theo cách bẩn, mà sẽ không cập nhật các tập tin cấu hình. Đây là những gì diễn ra dưới sự che chở của những điều trên ...

mv -i .git/refs/new-master .git/refs/master
git checkout master

65
2018-05-04 05:37



Cảm ơn bạn. Một câu hỏi nữa. Tôi đang đẩy nó vào github. Điều gì sẽ xảy ra ở đó, nếu tôi làm điều này? - Karel Bílek
@ Karel: Nó sẽ tạo ra một chút lộn xộn cho những người dùng khác; họ sẽ phải thiết lập lại chủ nhân của mình cho chủ nhân github. Nếu bạn muốn tránh gây rắc rối cho họ, hãy xem câu trả lời của tôi. - Cascabel
@ Dietrick Epp: Tôi không chắc liệu đó có phải là một ý hay hay không khi đề nghị cách bẩn thỉu. Nó sẽ làm hỏng theo dõi từ xa, reflogs ... không thể nghĩ ra bất kỳ lý do bạn đã bao giờ làm điều đó. - Cascabel
Ah, đó là một điểm tốt. Bạn có thể có cả hai cách, mặc dù: git branch old-master master; git branch -f master new-master. Tạo nhánh sao lưu mới, sau đó chuyển trực tiếp master sang master mới. (Và xin lỗi vì đã viết sai chính tả tên của bạn, chỉ cần chú ý rằng) - Cascabel
@ FakeName Tôi đã không kết luận không có lý do để làm điều đó, chỉ là không có lý do để làm điều đó cách bẩn thỉu. Bạn có thể làm điều đó bằng cách sử dụng lệnh bình thường (như trong bình luận trước đó của tôi) và nhận được kết quả tương tự, ngoại trừ reflogs nguyên vẹn và không có cơ hội borking mọi thứ. Và nó được đảm bảo để làm việc, vì bạn không mucking với các chi tiết thực hiện. - Cascabel


Đổi tên chi nhánh thành master bởi:

git branch -M branch_name master

40
2018-05-04 05:37



Thật không may git không theo dõi các renam nhánh chi nhánh, vì vậy nếu bạn đã đẩy repo của bạn đến một remote và những người khác có các thay đổi cục bộ trên nhánh master cũ của chúng, chúng sẽ gặp rắc rối. - thSoft
có sự khác biệt nào giữa điều này và git checkout master&&git reset --hard better_branch? - wotanii


Các giải pháp được đưa ra ở đây (đổi tên nhánh thành 'master') không nhấn mạnh vào hậu quả của repo từ xa (GitHub):

  • nếu bạn đã không đẩy bất cứ điều gì kể từ khi làm cho chi nhánh đó, bạn có thể đổi tên nó và đẩy nó mà không có bất kỳ vấn đề.
  • nếu bạn đã nhấn master trên GitHub, bạn sẽ cần phải 'git push -f' nhánh mới: bạn không còn có thể đẩy ở chế độ tua đi nhanh.
    -f
    --lực lượng

Thông thường, lệnh từ chối cập nhật một ref từ xa không phải là tổ tiên của ref địa phương được sử dụng để ghi đè lên nó. Cờ này sẽ vô hiệu hóa séc. Điều này có thể khiến kho lưu trữ từ xa bị mất các cam kết; sử dụng nó cẩn thận.

Nếu những người khác đã kéo repo của bạn, họ sẽ không thể kéo lịch sử tổng thể mới mà không thay thế chủ nhân của riêng mình bằng nhánh master mới của GitHub (hoặc xử lý nhiều hợp nhất).
lựa chọn thay thế cho một git push - force for repos công cộng.
Câu trả lời của Jefromi (sáp nhập các thay đổi đúng về chủ bản gốc) là một trong số chúng.


11
2018-05-04 05:57





Từ những gì tôi hiểu, bạn có thể chi nhánh nhánh hiện tại vào một nhánh hiện có. Về bản chất, điều này sẽ ghi đè lên master với bất kỳ thứ gì bạn có trong nhánh hiện tại:

git branch -f master HEAD

Một khi bạn đã làm điều đó, bạn có thể đẩy địa phương của bạn bình thường master chi nhánh, có thể yêu cầu lực lượng tham số ở đây là tốt:

git push -f origin master

Không có sự kết hợp, không có lệnh dài. Đơn giản branch và push- nhưng có, điều này sẽ viết lại lịch sử của master chi nhánh, vì vậy nếu bạn làm việc trong một nhóm, bạn phải biết bạn đang làm gì.




Ngoài ra, tôi thấy rằng bạn có thể đẩy bất kỳ chi nhánh nào vào bất kỳ nhánh từ xa nào, vì vậy:

# This will force push the current branch to the remote master
git push -f origin HEAD:master

# Switch current branch to master
git checkout master

# Reset the local master branch to what's on the remote
git reset --hard origin/master

10
2018-04-04 22:44



Rất đơn giản và hoạt động hoàn hảo! Hai lệnh git đơn giản và dễ hiểu. Repo git của tôi được lưu và bây giờ trông siêu sạch sẽ. Cảm ơn! - thehelix


Người ta cũng có thể kiểm tra tất cả các tập tin từ các chi nhánh khác vào master:

git checkout master
git checkout better_branch -- .

và sau đó cam kết tất cả các thay đổi.


6
2018-03-04 17:51





Tôi tìm thấy phương pháp đơn giản này để làm việc tốt nhất. Nó không viết lại lịch sử và tất cả các check-in trước đó của chi nhánh sẽ được thêm vào master. Không có gì bị mất, và bạn có thể thấy rõ những gì đã xảy ra trong nhật ký cam kết.

Mục tiêu: Tạo trạng thái hiện tại của "branch" là "master"

Làm việc trên một chi nhánh, cam kết và đẩy các thay đổi của bạn để đảm bảo các kho lưu trữ cục bộ và từ xa của bạn được cập nhật:

git checkout master      # Set local repository to master
git reset --hard branch  # Force working tree and index to branch
git push origin master    # Update remote repository

Sau này, chủ của bạn sẽ là trạng thái chính xác của lần commit cuối cùng của bạn và nhật ký commit chủ của bạn sẽ hiển thị tất cả các check-in của nhánh.


5
2018-04-08 15:30