Làm thế nào để thay thế chi nhánh địa phương bằng chi nhánh từ xa hoàn toàn trong Git?


779

Tôi có hai chi nhánh:

  1. chi nhánh địa phương (nơi tôi làm việc cùng)
  2. chi nhánh từ xa (công khai, chỉ có các cam kết được thử nghiệm tốt ở đó)

Gần đây tôi nghiêm túc làm hỏng chi nhánh địa phương của tôi.

Làm thế nào tôi có thể thay thế hoàn toàn chi nhánh địa phương bằng điều khiển từ xa, để tôi có thể tiếp tục công việc của mình từ nơi chi nhánh từ xa bây giờ?

Tôi đã tìm kiếm SO và kiểm tra chi nhánh từ xa không có bất kỳ ảnh hưởng nào.


1
Tôi biết câu trả lời được chấp nhận có 1280 lượt bình chọn, nhưng bạn thực sự nên xem xét việc thay đổi câu trả lời được chấp nhận thành câu trả lời của @TTT.
Jamie

Câu trả lời:


1289
  1. Hãy chắc chắn rằng bạn đã kiểm tra chi nhánh bạn đang thay thế (từ nhận xét của Zoltán ).
  2. Giả sử chủ đó là chi nhánh địa phương bạn đang thay thế và "origin / master" là chi nhánh từ xa bạn muốn đặt lại thành:

    git reset --hard origin/master
    

Điều này cập nhật nhánh CHÍNH cục bộ của bạn để được sửa đổi giống như nguồn gốc / bản gốc và --hardcũng sẽ đồng bộ hóa thay đổi này vào chỉ mục và không gian làm việc.


4
Cảm ơn lời đề nghị của bạn, tôi rất 'sợ' việc sử dụng --hard và - Force, vì vậy tôi chỉ chọn giải pháp không sử dụng những giải pháp đó.
YemSalat

13
@KonstantinLevin: ah vâng, việc đặt tên cho các tùy chọn đó khá khó chịu. git resettheo mặc định sẽ bổ nhiệm lại chi nhánh hiện tại của bạn và đồng bộ hóa chỉ mục. --softsẽ bỏ qua việc cập nhật chỉ mục, --hardcũng sẽ đồng bộ hóa không gian làm việc. Kinh nghiệm của riêng tôi là sử dụng --hardhầu hết thời gian, ngoại trừ khi tôi muốn hoàn tác cam kết cuối cùng (chỉ là git reset HEAD^)
araqnid

9
Sau khi có nhiều kinh nghiệm với git, tôi tin rằng đây là một giải pháp tốt hơn, cảm ơn.
YemSalat

24
có lẽ bạn sẽ cần tìm nạp trước:git fetch origin remote_branch
b1r3k

53
Bạn nên lưu ý rằng điều này sẽ thay thế bất kỳ chi nhánh nào của bạn hiện tại bằng nội dung của chủ . Vì vậy, nếu bạn đang ở ví dụ như một nhánh tính năng, nó sẽ thay thế tất cả các cam kết của nó master, vì vậy hãy chắc chắn rằng bạn đã kiểm tra chi nhánh bạn sẽ thay thế trước.
Zoltán

218

Điều đó dễ như ba bước:

  1. Xóa chi nhánh địa phương của bạn: git branch -d local_branch
  2. Lấy chi nhánh từ xa mới nhất: git fetch origin remote_branch
  3. Xây dựng lại chi nhánh địa phương dựa trên điều khiển từ xa: git checkout -b local_branch origin/remote_branch

7
Thật ra những gì @araqnid nói là đúng và ngắn gọn hơn. Tôi đã thử nó và bạn cũng có thể thử nó.
adamsmith

Ồ, kiểm tra git -b local_branch origin / remote_branch thật tuyệt! Tôi luôn luôn làm điều này trong hai lệnh riêng biệt. cảm ơn!
kendepelchin

11
Bạn có thể cần phải làm git branch -D local_branchtrong bước đầu tiên nếu chi nhánh của bạn không được hợp nhất.
szeryf

cảm ơn, tôi đã có một thời gian khó khăn khi sử dụng gitflow, sau khi xuất bản một chi nhánh và sau đó hoàn thành nó, tôi muốn đi đến chi nhánh bị xóa và giải pháp của bạn là cách duy nhất hoạt động, kéo dường như không hoạt động .. hoặc tôi đã xử lý đã không sử dụng tốt -
Decebal

2
chúng ta nên đảm bảo rằng nhánh hiện tại không phải là nhánh cần xóa.
a_secenthusiast

43
git branch -D <branch-name>
git fetch <remote> <branch-name>
git checkout -b <branch-name> --track <remote>/<branch-name>

Phần --track làm gì?
eonist

3
@GitSync, đây là những gì git help branchnói về --track. When creating a new branch, set up branch.<name>.remote and branch.<name>.merge configuration entries to mark the start-point branch as "upstream" from the new branch. This configuration will tell git to show the relationship between the two branches in git status and git branch -v. Furthermore, it directs git pull without arguments to pull from the upstream when the new branch is checked out. Tôi đã sửa lệnh này trong câu trả lời. Cảm ơn đã nâng điểm.
Sailesh

Vì vậy, theo thuật ngữ layman: nó thêm URL từ xa vào nhánh mới. Vì vậy, họ đang đồng bộ mãi mãi. Vì vậy, để nói chuyện.
eonist

2
Bạn có thể nói rằng nó chỉ để thuận tiện. Nếu bạn làm như vậy git status, nó sẽ báo cáo nếu chi nhánh địa phương của bạn ở phía trước hoặc phía sau chi nhánh từ xa nếu bạn có liên kết với họ. Ngoài ra, bạn có thể làm git pull(hoặc push) thay vì đầy đủ git pull <remote> <branch>nếu bạn đã đặt chi nhánh của mình theo dõi <remote/branch>.
sailesh

22

Thay thế mọi thứ bằng nhánh từ xa; nhưng , chỉ từ cùng một cam kết chi nhánh địa phương của bạn là trên:

git reset --hard origin/some-branch

HOẶC , nhận bản mới nhất từ chi nhánh từ xa và thay thế mọi thứ:

git fetch origin some-branch
git reset --hard FETCH_HEAD

Bên cạnh đó, nếu cần, bạn có thể xóa sạch các tệp và thư mục chưa được theo dõi mà bạn chưa cam kết:

git clean -fd

Các git cleanlệnh đã làm nó cho tôi. git reset hard origin/masterkhông xóa sạch các tập tin không bị theo dõi. Cảm ơn!
Mornor

9

Cách an toàn và đầy đủ nhất để thay thế chi nhánh địa phương hiện tại bằng điều khiển từ xa:

git stash
git merge --abort
git rebase --abort
git branch -M yourBranch replaced_yourBranch
git fetch origin yourBranch:yourBranch
git checkout yourBranch

Các stashdòng lưu các thay đổi mà bạn đã không cam kết. Các branchdòng di chuyển chi nhánh của bạn để một cái tên khác, giải phóng các tên gốc. Các fetchdòng lấy bản sao mới nhất của điều khiển từ xa. Các checkoutdòng tái tạo chi nhánh ban đầu như một chi nhánh theo dõi.

Hoặc là một hàm bash:

replaceWithRemote() {
    yourBranch=${1:-`git rev-parse --abbrev-ref HEAD`}
    git stash
    git merge --abort
    git rebase --abort
    git branch -M ${yourBranch} replaced_${yourBranch}_`git rev-parse --short HEAD`
    git fetch origin ${yourBranch}:${yourBranch}
    git checkout ${yourBranch}
}

mà đổi tên nhánh hiện tại thành một cái gì đó như thay thế_master_98d258f.


Có thể muốn bao gồm git stash poptrong quy trình làm việc. Nếu bạn muốn áp dụng lại các tập tin được lưu trữ của bạn.
eonist

Bạn làm gì với nhánh bị đâm? Tôi sợ nó sẽ xuất hiện trở lại ở đâu đó trong tương lai sau khi tôi quên mất nó dùng để làm gì.
Scott Biggie

1
@ScottBiggs Nếu bạn muốn loại bỏ nhánh bị kẹt, hãy sử dụng "git stash Clear".
Đánh dấu A. Durham

4

Tôi hơi ngạc nhiên khi không ai đề cập đến điều này; Tôi sử dụng nó gần như mỗi ngày:

git reset --hard @{u}

Về cơ bản, @{u}chỉ là viết tắt cho nhánh ngược dòng mà nhánh hiện tại của bạn đang theo dõi. Ví dụ, điều này thường tương đương với origin/[my-current-branch-name]. Nó tốt bởi vì nó là bất khả tri.

Hãy chắc chắn git fetchđầu tiên để có được bản sao mới nhất của chi nhánh từ xa.


1
Trông thật tuyệt, tôi đã mệt mỏi với việc sao chép và dán tên của chi nhánh để thiết lập lại!
pedroct92

1
Tôi đã có một vài trường hợp tôi đã thêm câu trả lời cho các câu hỏi cũ và câu trả lời của tôi đã được đưa lên bảng xếp hạng. Tôi hy vọng điều này không.
Jamie

3

Nó có thể được thực hiện theo nhiều cách, tiếp tục chỉnh sửa câu trả lời này để truyền bá quan điểm kiến ​​thức tốt hơn.

1) Đặt lại cứng

Nếu bạn đang làm việc từ chi nhánh phát triển từ xa, bạn có thể đặt lại CHÍNH về cam kết cuối cùng trên nhánh từ xa như sau:

git reset --hard origin/develop

2) Xóa chi nhánh hiện tại và kiểm tra lại từ kho lưu trữ từ xa

Xem xét, bạn đang làm việc về phát triển chi nhánh trong repo cục bộ, đồng bộ hóa với chi nhánh từ xa / phát triển, bạn có thể làm như sau:

git branch -D develop
git checkout -b develop origin/develop

3) Hủy bỏ hợp nhất

Nếu bạn ở giữa một hợp nhất xấu (thực hiện sai với nhánh sai) và muốn tránh hợp nhất để quay lại nhánh mới nhất như sau:

git merge --abort

4) Hủy bỏ cuộc nổi loạn

Nếu bạn ở giữa một rebase xấu, bạn có thể hủy yêu cầu rebase như sau:

git rebase --abort

2

Bạn có thể làm như @Hugo của @Laurent đã nói, hoặc bạn có thể sử dụng git rebaseđể xóa các cam kết bạn muốn thoát khỏi, nếu bạn biết những cam kết nào. Tôi có xu hướng sử dụng git rebase -i head~N(trong đó N là một số, cho phép bạn thao tác N cam kết cuối cùng) cho loại hoạt động này.


Trên thực tế, đó là lệnh 'git rebase' đã làm rối tung mọi thứ, sau đó một số hợp nhất bắt buộc và thiết lập lại cứng .. Dù sao, điều tôi đang tìm kiếm chỉ là một cách dễ dàng để kéo toàn bộ repo từ máy chủ từ xa mà không hợp nhất.
YemSalat

2

Các câu trả lời được lựa chọn là hoàn toàn đúng , tuy nhiên nó không để lại tôi với các mới nhất cam / push ...

Vì vậy, đối với tôi:

git reset --hard dev/jobmanager-tools
git pull  ( did not work as git was not sure what branch i wanted)

Vì tôi biết tôi muốn tạm thời đặt chi nhánh ngược dòng của mình trong một vài tuần tới một chi nhánh cụ thể (giống như chi nhánh tôi đã chuyển sang / kiểm tra trước đó và đã thiết lập lại cứng)

Vì vậy, SAU thiết lập lại

git branch --set-upstream-to=origin/dev/jobmanager-tools
git pull
git status    ( says--> on branch  dev/jobmanager-tools 

1

Nếu bạn muốn cập nhật chi nhánh hiện chưa được kiểm tra, bạn có thể làm:

git fetch -f origin rbranch:lbranch

0

Như được cung cấp trong lời giải thích đã chọn, git reset là tốt. Nhưng ngày nay chúng ta thường sử dụng các mô-đun phụ: kho lưu trữ bên trong kho. Ví dụ: nếu bạn sử dụng ZF3 và jQuery trong dự án của mình, bạn có thể muốn chúng được sao chép từ kho lưu trữ ban đầu của chúng. Trong trường hợp như vậy git reset là không đủ. Chúng tôi cần cập nhật các mô hình con lên phiên bản chính xác được xác định trong kho lưu trữ của chúng tôi:

git checkout master
git fetch origin master
git reset --hard origin/master
git pull

git submodule foreach git submodule update

git status

nó giống như bạn sẽ đến (cd) đệ quy vào thư mục làm việc của từng mô-đun phụ và sẽ chạy:

git submodule update

Và nó rất khác với

git checkout master
git pull

bởi vì các mô đun con trỏ không đến nhánh mà đến cam kết.

Trong trường hợp đó khi bạn kiểm tra thủ công một số nhánh cho 1 hoặc nhiều mô hình con, bạn có thể chạy

git submodule foreach git pull

Vui lòng cung cấp một lời giải thích, đặc biệt là khi trả lời câu hỏi cũ này. Câu trả lời của bạn là không hữu ích.
Erik A

Câu trả lời được chấp nhận đã đề xuất git reset --hard. Điều này thêm ít giá trị.
florisla

0
git reset --hard
git clean -fd

Điều này làm việc cho tôi - sạch sẽ hiển thị tất cả các tập tin nó đã xóa quá. Nếu nó cho bạn biết bạn sẽ mất các thay đổi, bạn cần phải bỏ qua.


-6

Cách xấu xí nhưng đơn giản hơn: xóa thư mục cục bộ của bạn và sao chép lại kho lưu trữ từ xa.


10
Hoặc chỉ cần xóa chi nhánh và kiểm tra lại.
nguyệt quế

Đúng, tôi đoán đó là những gì tôi sẽ làm nếu tôi không tìm ra cách thực hiện theo cách ít 'xấu xí' hơn
YemSalat

2
Xấu xí đôi khi hữu ích để biết. Tôi ước mọi người sẽ không hạ thấp mọi thứ chỉ vì chúng không phải là cách thông thường: phải có một lý do hợp lý hơn để hạ thấp ... và nó nên được đưa ra. Git là một thứ đạt được kết quả. Nó không phải là một loại văn bản thiêng liêng.
mike gặm nhấm

3
Tôi không hiểu các downvote :-( Vâng, nó không phù hợp, v.v. nhưng nó có thể hoạt động tốt nhất trong một số trường hợp ... xin lỗi @Hugo
silverdr

@Hugo, Đồng ý. Một cái gì đó bí ẩn và có mùi đã xảy ra với chi nhánh phát triển địa phương của tôi, và cả Trưởng nhóm và Giám đốc kỹ thuật đề nghị, trong số các giải pháp thanh lịch hơn, chỉ cần (zip, sao chép và lưu công việc tính năng của tôi, sau đó) nuke repo cục bộ và reclone.
AmitaiB
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.