Làm cách nào để sao chép phiên bản của một tệp từ nhánh git này sang nhánh khác?


944

Tôi đã có hai chi nhánh được hợp nhất hoàn toàn với nhau.

Tuy nhiên, sau khi hợp nhất được thực hiện, tôi nhận ra rằng một tệp đã bị nhầm lẫn bởi sự hợp nhất (một người khác đã thực hiện định dạng tự động, gah) và việc thay đổi sang phiên bản mới trong nhánh khác sẽ dễ dàng hơn sau đó chèn lại thay đổi một dòng của tôi sau khi đưa nó vào chi nhánh của tôi.

Vì vậy, cách dễ nhất trong git để làm điều này là gì?


3
Xin lưu ý rằng trong câu trả lời được chấp nhận, giải pháp đầu tiên sẽ thay đổi và giải pháp thứ hai thì không. stackoverflow.com/a/56045704/151841
user151841

Câu trả lời:


1674

Chạy phần này từ nhánh mà bạn muốn tệp kết thúc:

git checkout otherbranch myfile.txt

Công thức chung:

git checkout <commit_hash> <relative_path_to_file_or_dir>
git checkout <remote_name>/<branch_name> <file_or_dir>

Một số ghi chú (từ ý kiến):

  • Sử dụng hàm băm cam kết, bạn có thể kéo tệp từ bất kỳ cam kết nào
  • Điều này làm việc cho các tập tin và thư mục
  • ghi đè lên tập tin myfile.txtmydir
  • Ký tự đại diện không hoạt động, nhưng đường dẫn tương đối làm
  • Nhiều đường dẫn có thể được chỉ định

một thay thế:

git show commit_id:path/to/file > path/to/file

13
Vâng, nó sẽ. Nhưng đó là ý định của câu hỏi.
Ikke

37
Có thể rõ ràng, nhưng bạn cần sử dụng tên tệp đầy đủ ... Ký tự đại diện không hoạt động!
Chris Hart

6
mặc dù .. đó cũng là một cách hay: git show commit_id: path / to / file> path / to / file
milushov

14
từ xa: nguồn gốc kiểm tra git / otherbranch myfile.txt
Roman Rhrn Nesterov

6
Sử dụng các ký tự đại diện sẽ hoạt động, bạn chỉ cần bọc chúng lại ''để chúng không bị dịch bởi vỏ.
Wiktor Czajkowski

82

Tôi đã kết thúc câu hỏi này trên một tìm kiếm tương tự. Trong trường hợp của tôi, tôi đang tìm cách trích xuất một tệp từ một nhánh khác vào thư mục làm việc hiện tại khác với vị trí ban đầu của tệp. Trả lời :

git show TREEISH:path/to/file >path/to/local/file

18
Mục đích của 'git show' là xuất dữ liệu đến thiết bị đầu cuối ở định dạng có thể đọc được, điều này không được đảm bảo để khớp chính xác với nội dung của tệp. Tương tự như tốt hơn là sao chép toàn bộ tài liệu từ và không cố gắng Sao chép và Dán nội dung của nó sang tài liệu khác.
Gonen

Tôi chỉ muốn xem nó để tôi có thể so sánh nội dung với chi nhánh hiện tại (kiểm tra một số đoạn mã). Tôi muốn sử dụng vim với điều này mặc dù ... để làm nổi bật cú pháp, v.v.
isaaclw

3
Để so sánh nội dung trước khi thực hiện kiểm tra, git diff <other branch> <path to file>hoạt động tốt.
Randall

2
@Gonen: Kể từ phiên bản git 2.21.0, trang hướng dẫn "git show" có nội dung "Đối với các đốm màu đơn giản, nó hiển thị nội dung đơn giản." Tôi không chắc điều này có nghĩa là chúng ta luôn tốt. Tôi cảnh giác để lấy một hình ảnh theo cách đó ...
hibbelig

52

Điều gì về việc sử dụng lệnh thanh toán:

  git diff --stat "$branch"
  git checkout --merge "$branch" "$file"
  git diff --stat "$branch"

8
ghi chú hợp nhất (lệnh thứ 2) không thể hoạt động nếu tệp không tồn tại trên cả hai nhánh
đơn giản hóa

Hừm. Tôi không có diffstat. Đó có phải là phiên bản cụ thể của công cụ tìm khác biệt không, vì tôi chưa bao giờ nghe về nó (và tôi có nên chuyển sang sử dụng nó không?): D
dudewad

git diffhỗ trợ một --statđối số về cơ bản làm điều tương tự như diffstat.
hlovdal

Tôi đã phải kiểm tra cả hai chi nhánh tại địa phương để làm việc này.
UnitasBrooks

18

1) Đảm bảo bạn ở chi nhánh nơi bạn cần một bản sao của tệp. ví dụ: tôi muốn tập tin nhánh phụ trong master vì vậy bạn cần kiểm tra hoặc nên ở trong mastergit checkout master

2) Bây giờ hãy kiểm tra tệp cụ thể mà bạn muốn từ nhánh phụ thành chủ,

git checkout sub_branch file_path/my_file.ext

ở đây sub_branchcó nghĩa là nơi bạn có tệp đó theo sau là tên tệp bạn cần sao chép.


Rất tiện dụng và được giải thích tốt.
Abk

15

Theo câu trả lời của madlep, bạn cũng có thể sao chép một thư mục từ một nhánh khác với thư mục blob.

git checkout other-branch app/**

Đối với câu hỏi của op nếu bạn chỉ thay đổi một tập tin trong đó thì nó sẽ hoạt động tốt ^ _ ^


1
Lưu ý rằng cả hai nhánh cần được kéo đúng, trước tiên hoặc sử dụng origin/other-branchđể tham chiếu đến nhánh repo. Cơ bản, nhưng cắn tôi. (câu trả lời là tuyệt vời - không cần chỉnh sửa)
akauppi

8

Tôi sẽ sử dụng git restore(có sẵn từ git 2.23)

git restore --source otherbranch path/to/myfile.txt


Tại sao nó tốt hơn các lựa chọn khác?

git checkout otherbranch -- path/to/myfile.txt- Nó sao chép tập tin vào thư mục làm việc nhưng cũng vào khu vực tổ chức (hiệu ứng tương tự như khi bạn sao chép tập tin này bằng tay và thực hiện git addtrên nó). git restorekhông chạm vào khu vực tổ chức (trừ khi được nói với --stagedtùy chọn).

git show otherbranch:path/to/myfile.txt > path/to/myfile.txtsử dụng chuyển hướng vỏ tiêu chuẩn. Nếu bạn sử dụng Powershell thì có thể có vấn đề với việc đóng văn bản hoặc bạn có thể bị hỏng tệp nếu đó là tệp nhị phân . Với git restoreviệc thay đổi tập tin được thực hiện tất cả bằng cách gitthực thi.

Một ưu điểm khác là bạn có thể khôi phục toàn bộ thư mục với:

git restore --source otherbranch path/to

hoặc với git restore --overlay --source otherbranch path/tonếu bạn muốn tránh xóa các tập tin. Ví dụ: nếu có ít tệp trên otherbranchhơn trong thư mục làm việc hiện tại (và các tệp này được theo dõi ) mà không có --overlaytùy chọn git restoresẽ xóa chúng. Nhưng đây là bahaviour mặc định tốt, rất có thể bạn muốn trạng thái của thư mục giống như trong otherbranch, không phải "giống nhau mà là với các tệp bổ sung trong nhánh hiện tại của tôi"


Câu trả lời tốt đẹp. Có git restorecách nào để sao chép một tệp từ nhánh nguồn sang một tệp mới trên nhánh đích không? Với git show tôi có thể làm điều này với chuyển hướng shell ( git show otherbranch:path/to/file1.txt > path/to/file2.txt), nhưng tôi muốn tránh chuyển hướng shell vì những lý do bạn đã đề cập.
Đô đốcAdama

1
@AdmirusAdama không thực sự. Và tôi nghĩ rằng không có cơ hội lớn để có được nó git restore(nhưng ai biết được;)). Vấn đề chuyển hướng này về cơ bản là vấn đề Powershell, không chắc có lớp vỏ nào khác có vấn đề với nó không. Tôi thường quay lại "git bash" hoặc thậm chí "cmd" nơi tôi cần sử dụng git showcác lệnh " với chuyển hướng". Hoặc sử dụng GUI như GitExtensions nơi bạn có thể duyệt cây tệp cam kết và nhấp vào "Lưu dưới dạng" trên bất kỳ tệp nào.
Mariusz Pawelski

Ah tôi thấy. Tôi không sử dụng Powershell vì vậy có lẽ chuyển hướng vỏ là np cho tôi. Cảm ơn bạn về thông tin.
Đô đốcAdama

3

Hãy lưu ý rằng trong câu trả lời được chấp nhận, tùy chọn đầu tiên giai đoạn toàn bộ tập tin từ chi nhánh khác (như git add ...đã được thực hiện), và đó là lựa chọn thứ hai chỉ kết quả trong việc sao chép tập tin, nhưng không giai đoạn thay đổi (như nếu bạn có chỉ cần chỉnh sửa tập tin bằng tay và có sự khác biệt nổi bật).

Git sao chép tập tin từ một chi nhánh khác mà không dàn dựng nó

Thay đổi theo giai đoạn (ví dụ git add filename):

$ git checkout directory/somefile.php feature-B

$ git status
On branch feature-A
Your branch is up-to-date with 'origin/feature-A'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   directory/somefile.php

Những thay đổi nổi bật (không được dàn dựng hoặc cam kết):

$ git show feature-B:directory/somefile.php > directory/somefile.php

$ git status
On branch feature-A
Your branch is up-to-date with 'origin/feature-A'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   directory/somefile.php

no changes added to commit (use "git add" and/or "git commit -a")

Tôi nhận được "Feature-B không phải là một tập tin", tên chi nhánh xuất hiện trước, về điều này -> "> thư mục / somefile.php" điều này có thể thay đổi mã hóa của tập tin không?
Tiago Oliveira de Freitas
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.