ฉันจะคัดลอกเวอร์ชันของไฟล์เดียวจากสาขา git หนึ่งไปยังอีกที่ได้อย่างไร


944

ฉันมีสองสาขาที่รวมเข้าด้วยกันอย่างสมบูรณ์

อย่างไรก็ตามหลังจากการผสานเสร็จสิ้นฉันรู้ว่ามีไฟล์หนึ่งไฟล์สับสนโดยการรวม (มีคนอื่นทำรูปแบบอัตโนมัติ, gah) และมันจะง่ายกว่าที่จะเปลี่ยนเป็นเวอร์ชั่นใหม่ในสาขาอื่นและ จากนั้นแทรกการเปลี่ยนแปลงหนึ่งบรรทัดของฉันอีกครั้งหลังจากนำมาไว้ในสาขาของฉัน

ดังนั้นวิธีที่ง่ายที่สุดในคอมไพล์ในการทำเช่นนี้คืออะไร?


3
โปรดทราบว่าในคำตอบที่ได้รับการยอมรับโซลูชันแรกจะทำการเปลี่ยนแปลงและโซลูชันที่สองจะไม่ดำเนินการ stackoverflow.com/a/56045704/151841
user151841

คำตอบ:


1674

เรียกใช้จากสาขาที่คุณต้องการให้ไฟล์สิ้นสุด:

git checkout otherbranch myfile.txt

สูตรทั่วไป:

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

หมายเหตุบางประการ (จากความคิดเห็น):

  • การใช้แฮชการกระทำคุณสามารถดึงไฟล์จากการคอมมิต
  • ใช้งานได้กับไฟล์และไดเรกทอรี
  • เขียนทับไฟล์myfile.txtและmydir
  • สัญลักษณ์แทนไม่ทำงาน แต่เส้นทางสัมพัทธ์ทำ
  • สามารถระบุได้หลายเส้นทาง

ทางเลือก:

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

13
ใช่มันจะ แต่นั่นเป็นความตั้งใจของคำถาม
Ikke

37
อาจเห็นได้ชัด แต่คุณต้องใช้ชื่อไฟล์ที่สมบูรณ์ ... Wildcard ไม่ทำงาน!
Chris Hart

6
แม้ว่า .. ยังเป็นวิธีที่ดี: git show commit_id: path / to / file> path / to / file
milushov

14
ระยะไกล: คอมไพล์เช็คเอาต์กำเนิด / otherbranch myfile.txt
Roman Rhrn Nesterov

6
การใช้ไวลด์การ์ดใช้งานได้คุณเพียงแค่หุ้มมัน''เพื่อไม่ให้เชลล์ถูกตีความ
Wiktor Czajkowski

82

ฉันสิ้นสุดที่คำถามนี้ในการค้นหาที่คล้ายกัน ในกรณีของฉันฉันกำลังมองหาการแยกไฟล์จากสาขาอื่นไปยังไดเรกทอรีการทำงานปัจจุบันที่แตกต่างจากตำแหน่งดั้งเดิมของไฟล์ ตอบ :

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

18
ความตั้งใจของ 'git show' คือการส่งออกข้อมูลไปยังเครื่องปลายทางในรูปแบบที่อ่านได้ซึ่งไม่รับประกันว่าจะตรงกับเนื้อหาของไฟล์อย่างแน่นอน เหมือนกับการคัดลอกเอกสาร Word โดยรวมและไม่พยายามคัดลอกและวางเนื้อหาไปยังเอกสารอื่น
Gonen

ฉันแค่อยากจะดูมันเพื่อให้ฉันสามารถเปรียบเทียบเนื้อหากับสาขาปัจจุบัน (ตรวจสอบรหัสบางส่วน) ฉันต้องการใช้เป็นกลุ่มด้วยสิ่งนี้แม้ว่า ... สำหรับการเน้นไวยากรณ์ ฯลฯ
isaaclw

3
เพื่อเปรียบเทียบเนื้อหาก่อนที่จะทำการเช็คเอาต์git diff <other branch> <path to file>ทำงานได้ดี
Randall

2
@Gonen: ในฐานะของ git เวอร์ชั่น 2.21.0 หน้าคู่มือ "git show" บอกว่า "สำหรับ blobs ธรรมดามันแสดงเนื้อหาธรรมดา" ฉันไม่แน่ใจว่าสิ่งนี้หมายความว่าเราดีเสมอ ฉันค่อนข้างระวังที่จะดึงภาพออกมาในแบบนั้น ...
35418

52

สิ่งที่เกี่ยวกับการใช้คำสั่งเช็คเอาท์:

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

8
note merge (คำสั่งที่ 2) ไม่สามารถทำงานได้หากไฟล์ไม่มีอยู่ในทั้งสองสาขา
simpleuser

ฮึ่ม ฉันไม่มีความแตกต่าง นั่นเป็นรุ่นเฉพาะของเครื่องมือ diff เพราะฉันไม่เคยได้ยิน (และฉันควรเปลี่ยนเป็นเหรอ?): D
dudewad

git diffสนับสนุนการ--statโต้เถียงซึ่งโดยทั่วไปแล้วทำสิ่งเดียวกันกับ diffstat
hlovdal

ฉันต้องตรวจสอบทั้งสองสาขาในพื้นที่เพื่อให้สามารถใช้งานได้
UnitasBrooks

18

1) ให้แน่ใจว่าคุณอยู่ในสาขาที่คุณต้องการสำเนาของไฟล์ สำหรับเช่น: ฉันต้องการไฟล์สาขาย่อยในหลักดังนั้นคุณต้องเช็คเอาต์หรือควรจะอยู่ในระดับปริญญาโทgit checkout master

2) ตอนนี้เช็คเอาท์ไฟล์เฉพาะคนเดียวที่คุณต้องการจากสาขาย่อยเป็นหลัก

git checkout sub_branch file_path/my_file.ext

นี่sub_branchหมายถึงที่ที่คุณมีไฟล์นั้นตามด้วยชื่อไฟล์ที่คุณต้องการคัดลอก


มีประโยชน์มากและอธิบายได้ดี
Abk

15

ทำตามคำตอบของ madlep คุณสามารถคัดลอกไดเรกทอรีหนึ่งจากสาขาอื่นด้วยไดเรกทอรีหยด

git checkout other-branch app/**

สำหรับคำถามของ op หากคุณเปลี่ยนไฟล์เพียงไฟล์เดียวก็จะทำงานได้ดี ^ _ ^


1
ขอให้สังเกตว่าทั้งสองกิ่งจำเป็นต้องดึงอย่างถูกต้องก่อนหรือใช้origin/other-branchเพื่ออ้างถึงสาขา repo พื้นฐาน แต่ bit me (คำตอบนั้นยอดเยี่ยม - ไม่ต้องแก้ไข)
akauppi

8

ฉันจะใช้git restore(ใช้ได้ตั้งแต่ git 2.23)

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


ทำไมมันถึงดีกว่าตัวเลือกอื่น ๆ ?

git checkout otherbranch -- path/to/myfile.txt- มันคัดลอกไฟล์ไปยังไดเรกทอรีการทำงาน แต่ยังรวมถึงพื้นที่การแสดงละคร (ผลที่คล้ายกันเช่นถ้าคุณจะคัดลอกไฟล์นี้ด้วยตนเองและดำเนินการgit addเกี่ยวกับมัน) git restoreไม่ได้แตะพื้นที่การแสดงละคร (เว้นแต่จะระบุไว้ตาม--stagedตัวเลือก)

git show otherbranch:path/to/myfile.txt > path/to/myfile.txtใช้การเปลี่ยนเส้นทางเชลล์มาตรฐาน ถ้าคุณใช้ Powershell แล้วอาจจะมีปัญหากับ enconding ข้อความหรือคุณอาจจะได้รับไฟล์เสียถ้ามันไบนารี ด้วยgit restoreการเปลี่ยนไฟล์ทำได้โดยทั้งหมดgitปฏิบัติการ

ข้อดีอีกอย่างคือคุณสามารถกู้คืนทั้งโฟลเดอร์ได้ด้วย:

git restore --source otherbranch path/to

หรือด้วยgit restore --overlay --source otherbranch path/toถ้าคุณต้องการหลีกเลี่ยงการลบไฟล์ ตัวอย่างเช่นหากมีไฟล์น้อยotherbranchกว่าในไดเรกทอรีการทำงานปัจจุบัน (และไฟล์เหล่านี้มีการติดตาม ) โดยไม่มี--overlayตัวเลือกgit restoreจะลบพวกเขา แต่นี่เป็นค่าเริ่มต้นที่ดี bahaviour คุณน่าจะต้องการให้สถานะของไดเรกทอรีเหมือนกันotherbranchไม่ใช่ "เหมือนกัน แต่มีไฟล์เพิ่มเติมในสาขาปัจจุบันของฉัน"


คำตอบที่ดี มีgit restoreวิธีการคัดลอกไฟล์จากสาขาต้นทางไปยังไฟล์ใหม่ในสาขาเป้าหมายหรือไม่ ด้วย git show ฉันสามารถทำสิ่งนี้ได้ด้วยการเปลี่ยนเส้นทางเชลล์ ( git show otherbranch:path/to/file1.txt > path/to/file2.txt) แต่ฉันต้องการหลีกเลี่ยงการเปลี่ยนเส้นทางเชลล์ด้วยเหตุผลที่คุณพูดถึง
AdmiralAdama

1
@AdmiralAdama ไม่ได้จริงๆ และฉันคิดว่าไม่มีโอกาสที่จะเข้าร่วมได้git restore(แต่ใครจะรู้)) ปัญหาการเปลี่ยนเส้นทางนี้เป็นปัญหา Powershell โดยทั่วไปไม่แน่ใจว่ามีเชลล์อื่นที่มีปัญหาหรือไม่ ฉันมักจะกลับไปที่ "git bash" หรือแม้แต่ "cmd" ซึ่งฉันต้องใช้git showคำสั่ง" with redirection" หรือใช้ GUI เช่น GitExtensions ซึ่งคุณสามารถเรียกดูแผนผังไฟล์ของการคอมมิชชันและคลิก "บันทึกเป็น" บนไฟล์ใดก็ได้
Mariusz Pawelski

ฉันเข้าใจแล้ว ฉันไม่ได้ใช้ Powershell ดังนั้นบางทีการเปลี่ยนเส้นทางของเชลล์คือ np สำหรับฉัน ขอบคุณสำหรับข้อมูล.
AdmiralAdama

3

โปรดทราบว่าในคำตอบที่ได้รับการยอมรับตัวเลือกแรกจะทำขั้นตอนทั้งหมดของไฟล์จากสาขาอื่น (อย่างที่git add ...เคยทำ) และตัวเลือกที่สองจะส่งผลให้คัดลอกไฟล์ แต่จะไม่ทำการเปลี่ยนแปลง (เช่นถ้าคุณมี เพิ่งแก้ไขไฟล์ด้วยตนเองและมีความแตกต่างที่โดดเด่น)

Git คัดลอกไฟล์จากสาขาอื่นโดยไม่ต้อง staging

การเปลี่ยนแปลงจัดฉาก (เช่น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

การเปลี่ยนแปลงที่โดดเด่น (ไม่ใช่ staged หรือ commit):

$ 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")

ฉันได้รับ "คุณสมบัติ -B ไม่ใช่ไฟล์", ชื่อสาขามาก่อน, เกี่ยวกับเรื่องนี้ -> "> directory / somefile.php" สิ่งนี้อาจเปลี่ยนการเข้ารหัสไฟล์หรือไม่
Tiago Oliveira de Freitas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.