Làm thế nào để 'git pull' vào một nhánh không phải là chi nhánh hiện tại?


126

Khi bạn chạy git pulltrên masternhánh, nó thường kéo từ origin/master. Tôi đang ở một chi nhánh khác nhau gọi là newbranch, nhưng tôi cần phải chạy một lệnh mà không một git pulltừ origin/mastervào masternhưng tôi không thể chạy git checkoutđể thay đổi chi nhánh đã chọn cho đến sau khi kéo được hoàn tất. Có cách nào để làm việc này không?

Để cung cấp một số nền tảng, kho lưu trữ một trang web. Tôi đã thực hiện một số thay đổi newbranchvà triển khai chúng bằng cách chuyển trang web sang newbranch. Bây giờ những thay đổi đó đã được hợp nhất ngược dòng vào masterchi nhánh, tôi cũng đang cố gắng chuyển trang web trở lại masterchi nhánh. Tại thời điểm này, newbranchorigin/mastergiống hệt nhau, nhưng masterbị tụt lại phía sau origin/mastervà cần được cập nhật. Vấn đề là, nếu tôi làm theo cách truyền thống:

$ git checkout master
   # Uh oh, production website has now reverted back to old version in master
$ git pull
   # Website is now up to date again

Tôi cần phải đạt được như trên ( git checkout master && git pull), nhưng không thay đổi thư mục làm việc sang sửa đổi trước đó trong quá trình.


@phi: Tôi không nghĩ nó sẽ hoạt động, bởi vì tôi đang ở newbranchđó và không có gì ở đó!
Malvineous

Tôi sẽ sao chép vào một thư mục mới, hợp nhất newbranch thành master, hợp nhất master trở lại newbranch, sau đó git pull từ nơi bạn đang ở. Master và newbranch sẽ giống nhau.
AET

@aet Bây giờ anh ấy có thể làm điều đó trong thư mục hiện tại của mình bằng cách thực hiện git fetch; git merge origin/mastertừ bên trong newbranch. Không có lợi ích để nhân bản toàn bộ bản sao thứ hai của kho lưu trữ.
meagar

3
liên quan chặt chẽ: stackoverflow.com/questions/3216360/
Mạnh

Câu trả lời:


5

Bạn đã có một bàn làm việc mà bạn không muốn chạm vào, vì vậy hãy sử dụng một cái khác. Clone là giá rẻ, nó được xây dựng cho việc này.

git fetch origin master       # nice linear tree
git clone . ../wip -b master  # wip's `origin/master` is my `master`
cd ../wip                     # .
git pull origin origin/master # merge origin's origin/master
git push origin master        # job's done, turn it in.
cd ../main
rm -rf ../wip                 # wip was pushed here, wip's done

git checkout master           # payload

Vấn đề với tất cả các câu trả lời khác ở đây là, họ không thực sự làm được. Nếu bạn cần hợp nhất hoặc rebase bạn đã thiết lập pull, bạn cần một worktree khác và quy trình trên. Nếu không git fetch; git checkout -B master origin/mastersẽ chỉ làm.


2
Khi bạn chạy, git checkout masterbạn sẽ kiểm tra masterchi nhánh cũ vì bạn chưa thực hiện git pulltrong mainthư mục để đồng bộ hóa với nguồn gốc / bản gốc. Đây là những gì tôi đang cố gắng tránh.
Malvineous

Thanh toán được thực hiện bởi bản sao là của chủ cũ, nhưng thanh toán đó nằm trong một thư mục mà máy chủ web không nhìn vào. Thanh toán chính ở cuối là của tổng thể được hợp nhất hoàn toàn bị đẩy lùi khỏi lau.
jthill

Trên dòng 6, bạn đẩy việc hợp nhất (cập nhật) mastertrở lại origin, nhưng tôi không tin rằng lần kiểm tra cuối cùng của bạn là cập nhật này master. Không có git pullcập nhật masterchi nhánh trong mainthư mục, vì vậy trừ khi tôi thiếu thứ gì đó, các lệnh của bạn không khác gì chỉ tự chạy git checkout mastervà lấy mastercây cũ . Nếu bạn nhìn kỹ, bạn sẽ không chạy bất kỳ lệnh nào trong mainthư mục giao tiếp ngược dòng (ngoài dòng 1, được chạy trước khi bạn thực hiện bất kỳ thay đổi nào đối với repo ngược dòng.)
Malvineous

tốt, bạn có thể thử nó trên repo thử nghiệm hoặc kiểm tra tài liệu đẩy.
jthill

1
@jwg so với cái gì, làm ơn? Hãy chắc chắn để giải quyết tất cả các nhu cầu đã nêu của OP.
jthill

163

Đơn giản: Đang cập nhật từ một chi nhánh từ xa vào một chi nhánh hiện chưa check-out thạc sĩ :

git fetch origin master:master

nơi có nguồn gốc là từ xa của bạn và bạn đang kiểm tra ra ở một số ngành như dev .

Nếu bạn muốn cập nhật chi nhánh hiện tại của mình ngoài chi nhánh được chỉ định cùng một lúc:

git pull origin master:master

4
Hừm, có vẻ như nó không phải lúc nào cũng hoạt động; Tôi vừa được nhắc hợp nhất với chi nhánh WIP của mình.
gạch dưới

@underscore_d tương tự cho tôi.
Greg

1
Làm việc cho tôi ... nếu nó nhắc hợp nhất thì tôi tưởng tượng có những thay đổi trong chi nhánh của bạn mà bạn đang cập nhật không được cam kết với nguồn gốc
đọc lướt qua

2
Công việc này dự định làm như thế nào nhỉ? Nó không hoạt động đối với tôi, nó chỉ cố gắng hợp nhất nguồn gốc / chủ vào chi nhánh hiện đang thanh toán của tôi.
mooseerheijde 26/03/18

3
Điều này kéo chủ vào nhánh hiện tại. Điều này chắc chắn KHÔNG phải là những gì đang được yêu cầu. Nếu bạn thay đổi pull để tìm nạp, thì đây sẽ chính xác là những gì đang được yêu cầu.
Jeff Wolski

90

Điều này được trả lời ở đây: Hợp nhất, cập nhật và kéo các nhánh Git mà không cần sử dụng kiểm tra

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo

2
Điều này là tốt nhất, vì nó hoạt động với những thay đổi cục bộ không được cam kết.
Tomasz Gandor

2
Nếu bạn chỉ muốn bắt kịp với những thay đổi mới nhất bạn sẽ làm git fetch origin master:master. git fetchbởi chính nó sẽ cho rằng bạn có nghĩa là để cập nhật chi nhánh hiện tại chứ không phải một số chi nhánh khác.
John Leidegren

2
Đây là câu trả lời đơn giản và trực tiếp nhất. Đây phải là câu trả lời được chấp nhận IMO.
Keego

@JohnLeidegren - ngoại trừ không phải lúc nào nó cũng hoạt động như dự định. Xem bình luận để stackoverflow.com/a/42902058/274579 trả lời.
ysap

22

Hóa ra, câu trả lời rất đơn giản:

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Điều này cho phép bạn cập nhật masterchi nhánh mà không cần chuyển sang chi nhánh cho đến khi được cập nhật.


11
Điều này không làm những gì bạn yêu cầu làm thế nào.
jthill

Như nhận xét ở trên, câu hỏi mà bạn nghĩ ra không thực sự là câu hỏi mà bạn đã trả lời. Bạn nên cập nhật câu hỏi của mình để nó ít cụ thể hơn về việc sáp nhập vào một chi nhánh mà không kiểm tra nó, và nhiều hơn về việc chuyển trực tiếp sang phiên bản mới nhất của một chi nhánh có sẵn trên điều khiển từ xa mà không cần kiểm tra phiên bản cũ trước.
meagar

1
Đó hoàn toàn là câu trả lời tôi đến đây để tìm kiếm :)
Sophistifunk

1
Không phải những gì OP muốn, nhưng đã giúp tôi, thành thật.
Marcel Bro

1
@anoniim, không phải OP muốn gì? Ý bạn là OP vừa trả lời câu hỏi này?
smac89

12

Bạn lo lắng về một cái gì đó không thể sửa được, vì các hoạt động của Git không phải là nguyên tử. Bạn sẽ luôn có một lỗ hổng trong thư mục làm việc của bạn nửa đường giữa các chi nhánh, thậm chí nếu bạn cập nhật tổng thể mà không cần chuyển đổi đầu tiên với nó. Đây là lý do tại sao Git không phải là một công cụ triển khai .

Vì bạn không thực sự cam kết mã trong môi trường sản xuất của mình (tôi hy vọng), nên bạn thực sự không cần phải kiểm tra chi nhánh. Bạn chỉ có thể làm mộtgit fetch để cập nhật các ref từ xa của mình và sau đó git checkout origin/masterdi chuyển thư mục làm việc trực tiếp đến cam kết hiện được trỏ đến bởiorigin/master . Điều này sẽ đưa bạn vào trạng thái tách rời, nhưng một lần nữa, vì bạn không cam kết mã, điều này không thành vấn đề.

Đây là lỗ nhỏ nhất bạn sẽ nhận được, nhưng như tôi đã nói, một lỗ vẫn tồn tại; checkoutkhông phải là nguyên tử.


Tôi hiểu những hạn chế của việc sử dụng git để triển khai, vấn đề là lỗ hổng trong trường hợp này sẽ kéo dài vài phút thay vì dưới một giây. Ý tưởng tuyệt vời về việc kiểm tra origin/mastermặc dù, đó có thể chỉ là một mẹo nhỏ.
Malvineous

Điều gì làm cho lỗ "phút" dài? Kéo dữ liệu qua mạng? Chỉ cần làm một git fetchtrước khi bạn làm bất cứ điều gì khác và có được chuyển dữ liệu thực tế ra khỏi đường đi.
meagar

Sẽ mất vài phút vì một tệp (hiện tại) không bị theo dõi sẽ bị ghi đè bởi một cam kết trước đó. Vì vậy, tôi phải sao chép tập tin, làm công cụ git, sau đó đặt lại. "Phút dài" xuất phát từ tốc độ đánh máy của tôi. (Vâng, tôi có thể viết kịch bản nhưng nó chỉ để tạo ra một điểm khiến git tự làm mọi thứ nhanh hơn.)
Malvineous

3

Bạn có thể sử dụng update-ref cho việc này:

git fetch
git update-ref refs/heads/master origin/master
git checkout master

Lưu ý rằng điều này sẽ vứt bỏ mọi cam kết cục bộ trong nhánh chính. Trong trường hợp của bạn sẽ không có bất kỳ điều gì vì vậy điều này là ổn. Đối với những người khác đang cố gắng thực hiện việc này khi có các cam kết cục bộ, tôi không nghĩ là có thể, vì hợp nhất chỉ có thể được chạy trên chi nhánh hiện tại.


Điều này sẽ tương đương với git branch --force master origin/master? Điều này buộc người đứng đầu địa phương masterphải chỉ vào người đứng đầu của originsmaster
Keego

2

Giải pháp của Malvineous cho tôi

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Chỉ cần đưa ra lỗi


warning: not deleting branch 'master' that is not yet merged to
         'refs/remotes/origin/master', even though it is merged to HEAD.
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.

Vì vậy, tôi chạy với tùy chọn -D

cảm ơn


0

git fetch origin master:master

  • "Kéo" (thực sự tìm nạp) master.
  • Nếu bạn có những thay đổi masterchưa được đẩy, hãy origin/mastersáp nhập vào chủ của bạn.
  • Nếu có xung đột hợp nhất, bạn sẽ phải giải quyết chúng trước.
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.