2012-02-09 41 views
445

Tôi có hai nhánh:Thay thế chi nhánh địa phương với chi nhánh ở xa hoàn toàn

  1. chi nhánh địa phương (một trong những mà tôi làm việc với)
  2. chi nhánh từ xa (công cộng, chỉ được kiểm tra kỹ cam kết đi đến đó)

Gần đây tôi đã làm hỏng chi nhánh địa phương của tôi (đoán mỗi git-newbie đã ở vị trí của tôi tại một số thời điểm)

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

(Tôi đã tìm kiếm SO và kiểm tra ra các chi nhánh ở xa địa phương không có bất kỳ tác dụng)

Trả lời

753
  1. Đảm bảo bạn đã kiểm tra chi nhánh bạn đang thay thế (từ số comment của Zoltán).
  2. Giả sử tổng thể đó là chi nhánh địa phương bạn đang thay thế, và rằng "origin/master" là chi nhánh từ xa mà bạn muốn thiết lập lại để:

    git reset --hard origin/master 
    

này cập nhật chi nhánh ĐẦU địa phương để là bản sửa đổi giống như nguồn gốc/bản gốc và --hard cũng sẽ đồng bộ hóa thay đổi này vào chỉ mục và không gian làm việc.

+3

Cảm ơn lời đề nghị của bạn, tôi thật sự rất sợ hãi khi sử dụng - và tôi đã chọn giải pháp không sử dụng chúng. – YemSalat

+10

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

+0

@KonstantinLevin, khó hoặc lực là đáng sợ nhưng không phải" nhánh -d " (xóa bỏ)? Tôi thích giải pháp này, đơn giản và thẳng thắn. – km1

-5

Cách xấu xí nhưng đơn giản hơn: xóa thư mục địa phương của bạn, và clone kho từ xa một lần nữa.

+8

Hoặc chỉ cần xóa các chi nhánh và kiểm tra xem nó ra một lần nữa. –

+0

Vâng, tôi đoán đó là những gì tôi sẽ làm nếu tôi không tìm cách làm điều đó theo cách ít 'xấu xí' hơn – YemSalat

+0

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

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 loại bỏ, nếu bạn biết cái 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 lần commit cuối cùng) cho loại thao tác này.

+0

Thực ra đó là lệnh 'git rebase' đã làm rối tung mọi thứ, sau đó một số hợp nhất buộc và reset cứng .. Dù sao, những gì 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 cần hợp nhất. – YemSalat

26
git branch -D <branch-name> 
git fetch <remote> <branch-name> 
git checkout -b <branch-name> --track <remote>/<branch-name> 
+0

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

+2

@GitSync, Đây là những gì 'git help branch' nói về' --track'. 'Khi tạo một nhánh mới, hãy thiết lập nhánh. .remote và chi nhánh. nhập các mục cấu hình để đánh dấu chi nhánh điểm bắt đầu là "ngược dòng" từ nhánh mới. Cấu hình này sẽ cho git biết mối quan hệ giữa hai nhánh trong trạng thái git và git nhánh -v. Hơn nữa, nó chỉ đạo git kéo mà không có đối số để kéo từ thượng nguồn khi chi nhánh mới được kiểm tra ra.' Tôi đã cố định lệnh này trong câu trả lời. Cảm ơn bạn đã tăng điểm. – Sailesh

+0

Vì vậy, trong thuật ngữ người dùng: nó thêm URL từ xa vào nhánh mới. Vì vậy, chúng được đồng bộ hóa bao giờ hết. Vì vậy, để nói chuyện. – eonist

149

Đó là dễ dàng như ba bước:

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

Thực ra những gì @araqnid nói đúng và ngắn gọn hơn. Tôi đã thử nghiệm nó và bạn có thể thử nó quá. – adamsmith

+2

@ araqnid của câu trả lời dưới đây sẽ nhận được dấu kiểm –

+0

Wow, git checkout -b local_branch nguồn gốc/remote_branch là tuyệt vời! Tôi luôn làm điều này trong hai lệnh riêng biệt. cảm ơn! – kendepelchin

2

s câu trả lời được bầu là hoàn toàn chính xác, tuy nhiên nó đã không để lại cho tôi với cam kết/đẩy mới nhất ...

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) 

Kể từ khi tôi biết tôi muốn tạm thời thiết lập chi nhánh thượng nguồn của tôi cho một vài tuần đến một chi nhánh cụ thể (giống như một tôi chuyển sang/kiểm tra ra sớm hơn và đã làm một cứng reset trên)

Vì vậy SAU reset

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

Hmm, nó làm việc tốt cho tôi. Tôi không phải kéo. –

0

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

git fetch -f origin rbranch:lbranch 
2

Cách an toàn nhất và hoàn thiện nhất để thay thế các chi nhánh địa phương hiện tại với đ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 

Dòng stash lưu các thay đổi mà bạn đã không cam kết. Đường dây branch di chuyển chi nhánh của bạn đến một tên khác, giải phóng tên gốc. Dòng fetch truy xuất bản sao mới nhất của điều khiển từ xa. Dòng checkout tạo lại nhánh gốc làm nhánh theo dõi.

Hoặc như một chức năng 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} 
} 

đó đổi tên các chi nhánh hiện tại để cái gì đó như replaced_master_98d258f.

+0

Có thể muốn bao gồm 'git stash pop' trong luồng công việc đó. Nếu bạn muốn áp dụng lại các tệp đã lưu trữ của mình. – eonist

3

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

git reset --hard origin/some-branch 

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

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

Là một sang một bên, nếu cần, bạn có thể xóa sạch các tệp chưa được tải xuống & các thư mục mà bạn chưa cam kết:

git clean -fd 
0

Như được cung cấp trong phần giải thích đã chọn, git reset là tốt. Nhưng ngày nay chúng ta thường sử dụng 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 bạn, bạn có thể muốn chúng được nhân bản từ kho gốc của chúng. Trong trường hợp này, git reset là không đủ. Chúng ta cần phải cập nhật submodules với 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ó cũng giống như bạn sẽ đến (cd) một cách đệ quy vào thư mục làm việc của mỗi tiểu môđun và sẽ chạy:

git submodule update 

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

git checkout master 
git pull 

vì sub-module chỉ không cho chi nhánh nhưng với cam kết.

Trong những trường hợp đó khi bạn tự kiểm một số chi nhánh trong vòng 1 hoặc nhiều submodules bạn có thể chạy

git submodule foreach git pull 
+0

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

+0

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

Các vấn đề liên quan