Biến nhánh Git hiện tại thành nhánh chính


1657

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

Sau đó, hàng chục lần xác nhận sau đó, tôi nhận ra chi nhánh ở trạng thái tốt hơn nhiều so với chủ, vì vậy tôi muốn chi nhánh "trở thành" chủ và bỏ qua các thay đổi trên chủ.

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

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


2
Kiểm tra câu trả lời cho stackoverflow
nhau.com/q/2862590/151641

4
Có một vấn đề tương tự, tuy nhiên tôi chỉ cần xóa chủ và đổi tên một chi nhánh khác thành chủ: stackoverflow.com/a/14518201/189673
jayarjo

10
@jayarjo bạn nên tránh điều này nếu bạn có thể bởi vì nó sẽ viết lại lịch sử và gây ra vấn đề cho những người khác khi họ cố gắng kéo master.
joelittlejohn

3
Đây là lý do tại sao tôi thích câu trả lời của @Jefromi. Không có cấu trúc lịch sử của kho lưu trữ đang diễn ra.
froggythefrog

Câu trả lời:


2134

Vấn đề với hai câu trả lời khác là chủ mới không có chủ cũ làm tổ tiên, vì vậy 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 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ông điệp cam kết hợp nhất để làm rõ những gì 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

25
Lưu ý về "chiến lược" hợp nhất của git: --strategy=ourskhác với --strategy=recursive -Xours. Tức là "chúng ta" có thể là một chiến lược riêng (kết quả sẽ là chi nhánh hiện tại bất kể là gì) hoặc được chuyển qua 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 các thay đổi của chi nhánh hiện tại khi có xung đột ).
Kelvin

5
Tôi đã phải làm cho dòng thứ hai git merge --strategy=ours master -m "new master"cho nó hoạt động.
sợi đốt

5
@Johsm Đó chính xác là câu đầu tiên trong câu trả lời của tôi. Nếu bạn làm điều đó, chủ mới sẽ không có cùng lịch sử với chủ cũ, điều này rất tệ nếu bạn muốn đẩy / kéo. Bạn cần phải có chung tổ tiên để làm việc chính xác; nếu thay vào đó bạn làm những gì bạn đang nói, thì khi bạn cố gắng đẩy nó sẽ đơn giản là thất bại trừ khi bạn ép buộc (vì điều này là xấu và nó đang cố gắng ngăn cản bạn), và nếu bạn ép buộc, thì bất cứ ai sau đó cũng kéo sẽ cố gắng hợp nhất chủ cũ và chủ mới, có thể sẽ là một vụ đắm tàu.
Cascabel

4
Nếu trình soạn thảo vi trong khi hợp nhất xuất hiện, hãy nhập: w (để lưu): q (để thoát khỏi vi)
Tomas Kubes

9
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ể là người mới hoặc không chắc chắn) rằng bạn sẽ phải thực hiện git pushngay sau này nếu bạn muốn mã của mình được đẩy lên từ xa. Bạn có thể thấy một cảnh báo như thế Your branch is ahead of 'origin/master' by 50 commits.này được mong đợi. Chỉ cần đẩy nó! : D
nguyện

388

Đả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ủ" 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

81
Đâ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ế hoàn toàn chi nhánh. Điều này làm cho mọi thứ giống như tôi muốn, chỉ cần ghi đè lên nhánh và đẩy nó lên.
Gubatron

31
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 địa phương nào khác của repo sẽ cần đến git reset --hard origin/masterlần tiếp theo họ muốn kéo, nếu không, git sẽ cố gắng hợp nhất các thay đổi vào địa phương (hiện tại) của họ. Sự nguy hiểm của điều này được giải thích nhiều hơn trong câu trả lời này
7yl4r

3
cũng xin lưu ý rằng bạn cần được phép đẩ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
inetph Phantom

Nhược điểm ở đây cũng có thể là một nhược điểm tùy thuộc vào những gì mọi người muốn. Nếu bạn muốn đi xa như thay thế lịch sử của chủ nhân bằng lịch sử của chi nhánh khác, đây là câu trả lời của bạn.
b15

75

Chỉnh sửa: Bạn không nói rằng bạn đã bị đẩy vào một repo công khai! Điều đó làm 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 nhánh được đổi tên.

Bạn cũng có thể làm theo cách bẩn, sẽ không cập nhật các tệp cấu hình. Đây là loại những gì diễn ra dưới mui xe của ...

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

2
Cảm ơn bạn. Thêm một câu hỏi nữa. Tôi đang đẩy nó đến github. Điều gì sẽ xảy ra trên đó, nếu tôi làm điều này?
Karel Bílek

3
@Karel: Nó sẽ tạo ra một chút hỗn độn cho những người dùng khác; họ sẽ phải thiết lập lại chủ của mình thành chủ github. Nếu bạn muốn tránh gây ra cho họ bất kỳ rắc rối, hãy xem câu trả lời của tôi.
Cascabel

6
@Dietrick Epp: Tôi không chắc liệu có nên đề xuất cách bẩn hay không. Nó sẽ làm rối tung việc theo dõi từ xa, từ chối ... không thể nghĩ ra bất kỳ lý do nào bạn từng làm.
Cascabel

2
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 đó trực tiếp chuyển master sang new-master. (Và xin lỗi vì đã viết sai tên của bạn, chỉ cần chú ý điều đó)
Cascabel

2
@FakeName Tôi không kết luận rằng không có lý do để làm điều đó, chỉ là không có lý do để làm điều đó theo cách bẩn thỉu . Bạn có thể làm điều đó bằng cách sử dụng các lệnh thông thường (như trong nhận xét trước đây của tôi) và nhận được kết quả tương tự, ngoại trừ với các bản cập nhật còn nguyên vẹn và không có cơ hội làm hỏng mọi thứ. Và nó được đảm bảo để hoạt động, vì bạn không mucking với các chi tiết thực hiện.
Cascabel

46

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

git branch -M branch_name master

11
Thật không may, git không theo dõi việc đổi tên chi nhánh, vì vậy nếu bạn đã đẩy repo của mình đến một điều khiển từ xa và những người khác có thay đổi cục bộ trên nhánh chính cũ của địa phương, họ sẽ gặp rắc rối.
thSoft

Có sự khác biệt giữa cái này và git checkout master&&git reset --hard better_branch?
wotanii

26

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

git branch -f master HEAD

Khi bạn đã thực hiện điều đó, bạn thường có thể đẩy masterchi nhánh địa phương của mình , có thể yêu cầu tham số lực ở đây:

git push -f origin master

Không hợp nhất, không có lệnh dài. Đơn giản branchpush- nhưng, vâng, điều này sẽ viết lại lịch sử củamaster 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 đến bất kỳ chi 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

Rất đơn giản và làm việc 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!
thercix

16

Tôi đã tìm thấy câu trả lời tôi muốn trong bài đăng trên blog Thay thế nhánh chính bằng một nhánh khác trong git :

git checkout feature_branch
git merge -s ours --no-commit master
git commit      # Add a message regarding the replacement that you just did
git checkout master
git merge feature_branch

Về cơ bản, nó giống như câu trả lời của Cascabel . Ngoại trừ "tùy chọn" anh thêm vào bên dưới giải pháp của anh ấy đã được nhúng vào khối mã chính của tôi.

Tìm đường này dễ hơn.

Tôi đang thêm câu hỏi này như một câu trả lời mới, bởi vì nếu tôi cần giải pháp này sau này, tôi muốn có tất cảtôi sẽ sử dụng trong một khối mã.

Mặt khác, tôi có thể sao chép-dán, sau đó đọc chi tiết bên dưới để xem dòng mà tôi nên thay đổi - sau khi tôi đã thực hiện nó.


14

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

    -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 cục bộ được sử dụng để ghi đè lên nó. Cờ này vô hiệu hóa kiểm tra. Điều này có thể khiến kho lưu trữ từ xa bị mất các xác nhận; sử dụng nó một cách cẩn thận.

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


14

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 lần đăng ký trước của chi nhánh sẽ được thêm vào bản gốc. 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: Biến trạng thái hiện tại của "nhánh" thành "chủ"

Làm việc trên một chi nhánh, cam kết và thúc đẩy các thay đổi của bạn để đảm bảo các kho lưu trữ từ xa và cục bộ 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 xác nhận chi nhánh cuối cùng của bạn và nhật ký cam kết chính của bạn sẽ hiển thị tất cả các đăng ký của chi nhánh.


10

Người ta cũng có thể kiểm tra tất cả các tệp từ nhánh khác thành chủ:

git checkout master
git checkout better_branch -- .

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


5

Để thêm vào câu trả lời của Jefromi, nếu bạn không muốn đặt một sự hợp nhất vô nghĩa trong lịch sử của sourcechi nhánh, bạn có thể tạo một nhánh tạm thời cho việc ourshợp nhất, sau đó ném nó đi:

git checkout <source>
git checkout -b temp            # temporary branch for merge
git merge -s ours <target>      # create merge commit with contents of <source>
git checkout <target>           # fast forward <target> to merge commit
git merge temp                  # ...
git branch -d temp              # throw temporary branch away

Bằng cách đó, cam kết hợp nhất sẽ chỉ tồn tại trong lịch sử của targetchi nhánh.

Ngoài ra, nếu bạn không muốn tạo một sự hợp nhất nào cả, bạn chỉ cần lấy nội dung sourcevà sử dụng chúng cho một cam kết mới trên target:

git checkout <source>                          # fill index with contents of <source>
git symbolic-ref HEAD <target>                 # tell git we're committing on <target>
git commit -m "Setting contents to <source>"   # make an ordinary commit with the contents of <source>

3

Đối với tôi, tôi muốn devl của tôi trở lại với chủ sau khi nó ở phía trước.

Trong khi phát triển:

git checkout master
git pull

git checkout develop
git pull

git reset --hard origin/master
git push -f

2

Cách làm của tôi là như sau

#Backup branch
git checkout -b master_backup
git push origin master_backup
git checkout master
#Hard Reset master branch to the last common commit
git reset --hard e8c8597
#Merge
git merge develop

2

Nếu bạn đang sử dụng eGit trong Eclipse :

  • Nhấp chuột phải vào nút dự án.
  • Chọn đội → sau đó nâng cao → sau đó đổi tên chi nhánh
  • Sau đó mở rộng thư mục theo dõi từ xa .
  • Chọn chi nhánh có tên sai, sau đó nhấp vào nút đổi tên, đổi tên thành bất kỳ tên mới nào.
  • Chọn chủ mới, sau đó đổi tên thành chủ.

Tôi đã làm điều đó nhưng không chắc chắn nếu nó làm việc. Trên github, không có gì thay đổi nhưng trên phần mở rộng git tôi có thể thấy nhánh được đổi tên.
Pramod

0

Các bước sau đây được thực hiện trong trình duyệt Git được cung cấp bởi Atlassian (máy chủ Bitbucket)

Tạo {nhánh hiện tại} làm master

  1. Tạo một nhánh ra khỏi master và đặt tên cho nó là bản sao chính của bản sao.
  2. Tạo một nhánh ra khỏi {current-Branch} và đặt tên cho nó là {{nhánh hiện tại} -copy.
  3. Trong cài đặt kho lưu trữ (Bitbucket), hãy thay đổi nhánh mặc định của Verizon để chỉ điểm vào chính chủ nhân bản sao (không có bước này, bạn sẽ không thể xóa chính - trong bước tiếp theo).
  4. Xóa chi nhánh chính của nhánh - Tôi đã thực hiện bước này từ cây nguồn (bạn có thể thực hiện từ trình duyệt CLI hoặc Git)
  5. Đổi tên thành {hiện tại chi nhánh} Chuyển sang chủ Master và đẩy vào kho lưu trữ (điều này sẽ tạo ra một nhánh mới của nhánh chủ thời gian vẫn còn đó (hiện tại là nhánh}} sẽ tồn tại).
  6. Trong cài đặt kho lưu trữ, hãy thay đổi nhánh nhánh mặc định của Nhật Bản để chỉ điểm tại master master.
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.