Git clone รีโมตพื้นที่เก็บข้อมูลเฉพาะรุ่น


181

ฉันโคลนที่เก็บ git ระยะไกลประมาณหนึ่งเดือนที่แล้ว พื้นที่เก็บข้อมูลระยะไกลได้รับการเปลี่ยนแปลงมากมายและตอนนี้กลายเป็นไม่แน่นอน ตอนนี้ฉันต้องการสำเนาของที่เก็บอีกฉบับซึ่งเหมือนกับรุ่นที่ฉันโคลนเมื่อเดือนที่แล้ว

ฉันจะทำสิ่งนี้ได้อย่างไร


สำเนาซ้ำซ้อนที่เป็นไปได้ของstackoverflow.com/questions/3489173/ …
Nicolas Raoul

คำตอบ:


242

คุณสามารถ "รีเซ็ต" พื้นที่เก็บข้อมูลของคุณเป็นความมุ่งมั่นที่คุณต้องการ (เช่น 1 เดือนที่ผ่านมา)

ใช้git-resetสำหรับสิ่งนั้น:

git clone [remote_address_here] my_repo
cd my_repo
git reset --hard [ENTER HERE THE COMMIT HASH YOU WANT]

27
คุณไม่ได้พูดถึง แต่จะรีเซ็ตเฉพาะmasterสาขาซึ่งจะถูกเช็คเอาท์โดยค่าเริ่มต้นในโคลน หากสาขาอื่นที่ไม่ใช่masterสาขาการพัฒนาหลักของคุณที่ต้องเช็คเอาท์ก่อนgit reset
Steve Folly

16
ทำไมคุณไม่เช็คเอาท์แบบง่ายๆที่ต้องการ?
nemoo

10
เพราะคุณจะอยู่ในสถานะ "ถอดหัว" หลังจากเช็คเอาต์เพื่อกระทำการเฉพาะ
Rui Carneiro

6
@RuiCarneiro จะเป็นการดีกว่าgit checkout -b new_branch hashถ้าคุณใช้สร้างสาขาใหม่ตามแฮชโดยไม่ต้องไปที่สาขาอื่น การย้ายส่วนหัวของสาขาที่มีอยู่อาจทำให้เกิดปัญหาเมื่อถึงเวลาส่งบางสิ่งไปยังเซิร์ฟเวอร์ระยะไกล
Loïc Faure-Lacroix

1
@YuriGhensev หากความมุ่งมั่นได้ถูกผลักไปยังสาขาระยะไกลแล้วคุณสามารถทำgit pull origin [branch]อย่างอื่น afaik มันหายไป
Rui Carneiro

94

คุณสามารถใช้งานได้ง่าย

git checkout  commithash

ในลำดับนี้

git clone `URLTORepository`
cd `into your cloned folder`
git checkout commithash

กระทำแฮดูเหมือนว่า "45ef55ac20ce2389c9180658fdba35f4a663d204"


9
ฉันชอบคำตอบนี้ดีที่สุด ผมคิดว่าควรจะหลีกเลี่ยงในความโปรดปรานของgit reset --hard git checkout commit-hashการgit reset --hardลบส่วนหนึ่งของประวัติคอมไพล์ซึ่งบางครั้งก็ไม่เป็นที่ต้องการ
Jordan Stewart

8
git initไม่จำเป็น
Lautaro Paskevicius

37

ใช้git logเพื่อค้นหาการแก้ไขที่คุณต้องการย้อนกลับไปและจดแฮชการกระทำ หลังจากนั้นคุณมี 2 ตัวเลือก:

  1. หากคุณวางแผนที่จะกระทำการใด ๆ หลังจากการแก้ไขนั้นฉันขอแนะนำให้คุณชำระเงินไปยังสาขาใหม่:git checkout -b <new_branch_name> <hash>

  2. หากคุณไม่ได้วางแผนที่จะกระทำอะไรหลังจากการแก้ไขนั้นคุณก็สามารถเช็คเอาท์ได้โดยไม่ต้องสาขา: git checkout <hash>- หมายเหตุ: นี้จะทำให้พื้นที่เก็บข้อมูลของคุณใน 'แฝดหัว' ของรัฐซึ่งหมายความว่าขณะนี้ไม่ยึดติดกับทุกสาขา - แล้วคุณ' จะมีบางส่วนทำงานพิเศษเพื่อตัดใหม่กระทำไปยังสาขาที่เกิดขึ้นจริง

ตัวอย่าง:

$ git log
commit 89915b4cc0810a9c9e67b3706a2850c58120cf75
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:15:01 2010 -0300

    Added a custom extension.

commit 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:13:48 2010 -0300

    Missing constness.

$ git checkout 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Note: moving to '4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7'
which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 4553c14... Missing constness.

ด้วยวิธีนี้คุณจะไม่สูญเสียข้อมูลใด ๆ ดังนั้นคุณสามารถย้ายไปยังการแก้ไขที่ใหม่กว่าเมื่อมันมีเสถียรภาพ


2
แต่ยังไม่ได้ว่าคุณอยู่ในหัวเดี่ยวซึ่งก็โอเคสำหรับการดำเนินการอ่านอย่างเดียว แต่เมื่อคุณต้องการทำการเปลี่ยนแปลงเริ่มต้นที่การแก้ไขนี้คุณต้องสร้างสาขาใหม่ ดูsitaramc.github.com/concepts/detached-head.htmlสำหรับข้อมูลเพิ่มเติม
ฤดี

@Rudi: ขอบคุณ มันเป็นเพียงตัวอย่างเพื่อแสดงการใช้งาน อัปเดตที่จะพูดถึงมัน
jweyrich

เพื่อกลับไปที่ "สถานะการทำงาน" คุณสามารถgit checkout developพัฒนาชื่อสาขาของคุณได้
Steve Tauber

1
@SteveTauber ถ้าคุณมีสาขาอื่นที่ใช้งานได้การเปลี่ยนเป็นสาขานั้นก็เพียงพอแล้ว
jweyrich

19

หากเวอร์ชันนั้นคุณต้องได้รับอาจเป็นสาขาหรือแท็ก:

git clone -b branch_or_tag_name repo_address_or_path

2

ซึ่งแตกต่างจากระบบควบคุมรุ่นรวมศูนย์ Git โคลนที่เก็บทั้งหมดดังนั้นคุณไม่เพียง แต่จะได้รับไฟล์ระยะไกลปัจจุบัน แต่ประวัติทั้งหมด ที่เก็บในตัวคุณจะรวมทั้งหมดนี้

อาจมีแท็กเพื่อทำเครื่องหมายเวอร์ชันเฉพาะในขณะนั้น ถ้าไม่คุณสามารถสร้างมันด้วยตัวคุณเองในพื้นที่ วิธีที่ดีในการทำเช่นนี้คือการใช้git logหรืออาจใช้เครื่องมือที่มองเห็นได้มากกว่าgitk(อาจgitk --allเห็นกิ่งและแท็กทั้งหมด) หากคุณสามารถมองเห็นแฮชการกระทำที่ใช้ในเวลานั้นคุณสามารถติดแท็กแฮชเหล่านั้นโดยใช้git tag <hash>แล้วตรวจสอบสิ่งเหล่านั้นในสำเนาการทำงานใหม่ (ตัวอย่างเช่นgit checkout -b new_branch_name tag_nameหรือโดยตรงกับแฮชแทนชื่อแท็ก)


1

คุณสามารถแก้ไขได้ดังนี้:

git reset --hard sha

ที่ไหนshaเช่น:85a108ec5d8443626c690a84bc7901195d19c446

คุณสามารถรับ sha ที่ต้องการด้วยคำสั่ง:

git log

1

uploadpack.allowReachableSHA1InWant

เนื่องจากGit 2.5.0ตัวแปรการกำหนดค่านี้สามารถเปิดใช้งานบนเซิร์ฟเวอร์ได้ที่นี่คำขอคุณลักษณะ GitHubและGitHub ยอมรับการเปิดใช้งานคุณลักษณะนี้

Bitbucket Server เปิดใช้งานตั้งแต่รุ่น 5.5 ขึ้นไป

การใช้งาน:

# Make remote with 4 commits, and local with just one.
mkdir server
cd server
git init
touch 1
git add 1
git commit -m 1
git clone ./ ../local
for i in {2..4}; do
    touch "$i"
    git add "$i"
    git commit -m "$i"
done

# Before last commit.
SHA3="$(git log --format='%H' --skip=1 -n1)"
# Last commit.
SHA4="$(git log --format='%H' -n1)"

# Failing control without feature.
cd ../local
# Does not give an error, but does not fetch either.
git fetch origin "$SHA3"
# Error.
git checkout "$SHA3"

# Enable the feature.
cd ../server
git config uploadpack.allowReachableSHA1InWant true

# Now it works.
cd ../local
git fetch origin "$SHA3"
git checkout "$SHA3"
# Error.
git checkout "$SHA4"

0

แผนผังต้นไม้ที่คุณต้องการนั้นยังคงมีอยู่ในพื้นที่เก็บข้อมูล git อย่างไรก็ตามคุณจะต้องใช้ SHA1 ของการส่งข้อมูลที่คุณสนใจฉันจะสมมติว่าคุณสามารถรับ SHA1 จากโคลนปัจจุบันที่คุณมีอยู่ได้หรือไม่

หากคุณสามารถรับ SHA1 นั้นได้คุณสามารถสร้างสาขา / รีเซ็ตที่นั่นเพื่อให้มีพื้นที่เก็บข้อมูลเหมือนกัน

คำสั่งตามคำตอบของรุย


0

อาจgit resetแก้ปัญหาของคุณได้

git reset --hard -#commit hash-
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.