การย้ายจาก CVS ไปเป็น Git: $ Id $ equivalent?


124

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

ฉันเข้าใจว่าสิ่งนี้ไม่ค่อยสมเหตุสมผลในที่เก็บแบบกระจาย แต่ในฐานะนักพัฒนาฉันต้องการ / ต้องการอะไรแบบนี้ ให้ฉันอธิบายว่าทำไม:

ฉันใช้ Emacs เป็นระยะ ๆ ฉันจะค้นหาไฟล์ต้นฉบับ Lisp เวอร์ชันใหม่สำหรับแพ็คเกจของบุคคลที่สาม สมมติว่าฉันมีไฟล์ foo.el ซึ่งตามส่วนหัวคือเวอร์ชัน 1.3 ถ้าฉันค้นหาเวอร์ชันล่าสุดและเห็นว่ามันคือ 1.143 หรือ 2.6 หรืออะไรก็ตามฉันรู้ว่าฉันค่อนข้างล้าหลัง

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

ในฐานะนักพัฒนาฉันต้องการขยายความเอื้อเฟื้อนี้ให้กับผู้คนที่ใช้ผลลัพธ์ของฉัน (และบางทีฉันอาจล้อเล่นว่าใครเป็นใคร แต่ขอทิ้งไว้สักครู่) ฉันไม่อยากจำที่จะต้องเพิ่มจำนวนแช่งตัวเองทุกครั้งหรือการประทับเวลาหรืออะไรทำนองนั้น นั่นเป็น PITA ที่แท้จริงและฉันรู้จากประสบการณ์

ฉันมีทางเลือกอะไรบ้าง? หากฉันไม่สามารถรับ $ Id: $ เทียบเท่าฉันจะให้สิ่งที่ฉันกำลังมองหาได้อย่างไร

ฉันควรพูดถึงว่าความคาดหวังของฉันคือผู้ใช้ปลายทางจะไม่ได้ติดตั้ง Git และแม้ว่าพวกเขาจะทำ แต่ก็จะไม่มีที่เก็บในเครื่อง (แน่นอนฉันคาดว่าจะไม่ทำให้มันพร้อมใช้งานด้วยวิธีนั้น)

คำตอบ:


67

SHA เป็นเพียงการแสดงเวอร์ชันเดียว (แม้ว่าจะเป็นแบบบัญญัติ) git describeคำสั่งข้อเสนออื่น ๆ และไม่ให้ได้ค่อนข้างดี

ตัวอย่างเช่นเมื่อฉันรันgit describeในสาขาหลักของซอร์สไคลเอ็นต์ Java memcached ของฉันฉันจะได้รับสิ่งนี้:

2.2-16-gc0cd61a

ที่กล่าวถึงสองสิ่งที่สำคัญ:

  1. มีการคอมมิต 16 อย่างในต้นไม้นี้ตั้งแต่ 2.2
  2. แน่นอนแหล่งต้นไม้สามารถแสดงผลบนโคลนของคนอื่น

ตัวอย่างเช่นคุณจัดแพ็กเกจversionไฟล์ด้วยซอร์ส (หรือแม้กระทั่งเขียนเนื้อหาทั้งหมดใหม่เพื่อแจกจ่าย) เพื่อแสดงหมายเลขนั้น สมมติว่าเวอร์ชันแพ็กเกจคือ2.2-12-g6c4ae7a(ไม่ใช่รีลีส แต่เป็นเวอร์ชันที่ถูกต้อง)

ตอนนี้คุณสามารถเห็นได้อย่างชัดเจนว่าคุณอยู่เบื้องหลัง (4 คอมมิต) เพียงใดและคุณจะเห็นว่า 4 ข้อตกลงใด:

# The RHS of the .. can be origin/master or empty, or whatever you want.
% git log --pretty=format:"%h %an %s" 2.2-12-g6c4ae7a..2.2-16-gc0cd61a
c0cd61a Dustin Sallings More tries to get a timeout.
8c489ff Dustin Sallings Made the timeout test run on every protocol on every bui
fb326d5 Dustin Sallings Added a test for bug 35.
fba04e9 Valeri Felberg Support passing an expiration date into CAS operations.

1
การใช้สิ่งนี้จะล้มเหลวเมื่อคุณรวมสาขาการพัฒนาในขณะที่ต้นแบบมีโปรแกรมแก้ไขด่วนบางอย่าง จำนวนคอมมิตตั้งแต่เวอร์ชันล่าสุดจะเปลี่ยนไป แฮชไม่น่าเชื่อถือเนื่องจากมีใครบางคนสามารถสร้างใหม่ทั้งหมดด้วยfilter-branchหรือบางสิ่งบางอย่าง
LeMike

การเขียนจะอธิบายเฉพาะการเรียนรู้ข้อมูลเท่านั้นไม่ได้ฝังไว้ในไฟล์ปฏิบัติการของคุณ สำหรับสิ่งนั้นคุณต้องรันgit describeคำสั่งก่อนสร้างบันทึกผลลัพธ์ในไฟล์ส่วนหัวหรือฝังค่าในโค้ดของคุณ
Jesse Chisholm

56

ตอนนี้มีการรองรับ $ Id: $ ใน Git แล้ว หากต้องการเปิดใช้งานไฟล์READMEคุณต้องใส่ "README ident" ลงใน. gitattributes รองรับสัญลักษณ์แทนบนชื่อไฟล์ ดูman gitattributesสำหรับรายละเอียด


14
สิ่งนี้ให้ sha1 ของ blob แต่ไม่ใช่ sha1 ของการคอมมิต มีประโยชน์ไม่ใช่เป็นเพียงตัวระบุสำหรับการคอมมิต
Stephen Jennings

4
git ไม่มีกลไกการขยายคำหลักเหมือนที่$Id$กล่าวถึง สิ่งที่เก็บไว้คือสิ่งที่คุณได้รับ ไม่ว่าในกรณีใดเวอร์ชันนี้เป็นของคอลเลกชันไฟล์ทั้งหมดที่สร้างการกระทำไม่ใช่เฉพาะไฟล์ใดไฟล์หนึ่ง (ความคิดนั้นเป็นส่วนที่เหลือจากวัน RCS หรือ SCCS อาจจะตำหนิที่นี่ ... เนื่องจาก CVS เป็นเพียง ส่วนหน้าที่ได้รับการยกย่องให้เป็น RCS และ SVN พยายามที่จะเป็น CVS ที่ใช้งานได้จริง
vonbrand

32

นี่ไม่ใช่คำขอที่ไม่มีเหตุผลจาก OP

กรณีการใช้งานของฉันคือ:

  1. ฉันใช้ Git สำหรับรหัสส่วนตัวของฉันเองดังนั้นจึงไม่มีการร่วมมือกับผู้อื่น
  2. ฉันเก็บสคริปต์ Bash ของระบบไว้ในนั้นซึ่งอาจเข้าสู่/usr/local/binเมื่อพร้อม

ฉันใช้เครื่องสามเครื่องที่แยกจากกันโดยมีที่เก็บ Git เดียวกัน คงจะดีไม่น้อยหากทราบว่า "เวอร์ชัน" ของไฟล์ที่ฉันมีอยู่ในขณะนี้/usr/local/binโดยไม่ต้องทำคู่มือ "diff -u <repo version> <version in / usr / local / bin>" ด้วยตนเอง

สำหรับคนที่คิดลบอย่าลืมว่ามีกรณีการใช้งานอื่น ๆ อยู่ที่นั่น ไม่ใช่ทุกคนที่ใช้ Git สำหรับการทำงานร่วมกันกับไฟล์ในที่เก็บ Git ซึ่งเป็นตำแหน่ง "สุดท้าย"

อย่างไรก็ตามวิธีที่ฉันทำคือสร้างไฟล์แอตทริบิวต์ในที่เก็บเช่นนี้:

cat .git/info/attributes
# see man gitattributes
*.sh ident
*.pl ident
*.cgi ident

จากนั้นใส่ $ Id $ ไว้ที่ไหนสักแห่งในไฟล์ (ฉันชอบใส่ไว้หลัง shebang)

การกระทำ โปรดทราบว่าสิ่งนี้ไม่ได้ทำการขยายโดยอัตโนมัติอย่างที่ฉันคาดไว้ คุณต้องรวมไฟล์อีกครั้งตัวอย่างเช่น

git commit foo.sh
rm foo.sh
git co foo.sh

จากนั้นคุณจะเห็นการขยายตัวอย่างเช่น:

$ head foo.sh
#!/bin/sh

# $Id: e184834e6757aac77fd0f71344934b1cd774e6d4 $

ข้อมูลดีๆบางส่วนอยู่ในฉันจะเปิดใช้งานสตริงรหัสสำหรับที่เก็บ Git ได้อย่างไร .


3
ควรสังเกตว่าสิ่งนี้ระบุไฟล์ปัจจุบัน(หยด) ไม่ใช่การคอมมิตปัจจุบัน
CharlesB

3
สิ่งที่git coควรทำ? ฉันได้รับข้อความแสดงข้อผิดพลาด " git: 'co' is not a git command. See 'git --help'." ควรจะเป็นgit checkout ?
Peter Mortensen

23

ไม่แน่ใจว่าสิ่งนี้จะอยู่ใน Git เพื่อเสนอราคา Linus :

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

มันค่อนข้างง่ายที่จะตรวจสอบบันทึก - หากคุณกำลังติดตามสาขาที่มั่นคงของ foo.el คุณสามารถดูว่ามีข้อตกลงใหม่ใดบ้างในบันทึกของสาขาที่มีเสถียรภาพซึ่งไม่ได้อยู่ในสำเนาในเครื่องของคุณ หากคุณต้องการจำลองหมายเลขเวอร์ชันภายในของ CVS คุณสามารถเปรียบเทียบการประทับเวลาของคอมมิตล่าสุดได้

แก้ไข: คุณควรเขียนหรือใช้สคริปต์ของผู้อื่นสำหรับสิ่งนี้แน่นอนว่าอย่าทำด้วยตนเอง


26
ใช่ฉันอ่านส่วนหนึ่งของอีเมลยาว ๆ เกี่ยวกับการขยายคำหลัก ท่าทีของไลนัสเกือบจะเพียงพอที่จะทำให้ฉันเลิกยุ่งได้อย่างสมบูรณ์
Joe Casadonte

15
ใช่บางครั้งเขาขาดความสุภาพ แต่เขามักจะถูกต้องและแน่นอนเขาอยู่ในหัวข้อของการขยายคำหลัก
Bombe

จำเป็นต้องมีการติดตามเวอร์ชัน git ถูกใช้ในโครงสร้างพื้นฐานอื่น ๆ นอกเหนือจากการพัฒนาที่บริสุทธิ์ซึ่งเราสามารถอ่านรหัสเพื่อพิจารณาว่าเหมาะสมหรือไม่ แต่เมื่อระบบควบคุมการแก้ไขถูกใช้เพื่อติดตามไฟล์ที่มีเนื้อหาตามอำเภอใจคุณจะต้องมีวิธีการบางอย่างในการทราบรุ่นอย่างเป็นทางการ git นับประสาอะไรกับบันทึก git ไม่ได้อยู่ในเครื่องซึ่งมีการพุช. ini, .conf, .html และไฟล์อื่น ๆ
rjt

7
Linus แสดงความคิดเห็นเกี่ยวกับการขยายคำหลักเพียงด้านเดียวนั่นคือการติดตามการเผยแพร่ แต่ไม่ใช่จุดประสงค์เดียวของมัน คำพูดนั้นแสดงให้เห็นถึงทัศนคติของชายคนหนึ่งอย่างชัดเจน แต่ไม่มีประโยชน์อะไรเกี่ยวกับเรื่องนี้ กลอุบายทางการเมืองโดยทั่วไป "ระบุชัดเจนในทางที่สูงส่ง" และฝูงชนก็เป็นของคุณ ปัญหาคือฝูงชนตามคำจำกัดความโง่เพราะมีสมองเพียงอย่างเดียวในทุกเรื่อง ซึ่งอธิบายสถานการณ์ด้วยการขยายคอมไพล์และคีย์เวิร์ดอย่างชัดเจน คนงี่เง่าคนหนึ่งบอกว่า "ไม่" และทุกคนก็โห่ร้อง!
AnrDaemon

1
@AnrDaemon ไม่เพียงแค่นั้นตอนนี้ git ได้เพิ่มการรองรับ$Id$ผ่านidentแอตทริบิวต์ดังที่ได้กล่าวไว้ในคำตอบอื่นที่นี่แสดงให้เห็นว่าแม้แต่คอมไพล์เองก็ไม่ได้เป็นตัวประกันต่อความคิดเห็นของ Linus
orip

21

ในฐานะที่ผมเคยเขียนมาก่อน :

การมีแท็ก Id ที่สร้างขึ้นโดยอัตโนมัติซึ่งแสดงหมายเลขเวอร์ชันที่เหมาะสมนั้นไม่สามารถทำได้ด้วยเครื่องมือ DSCM เช่น Bazaar เนื่องจากสายการพัฒนาของทุกคนอาจแตกต่างจากคนอื่น ๆ ทั้งหมด ดังนั้นใครบางคนอาจอ้างถึงเวอร์ชัน“ 1.41” ของไฟล์ แต่เวอร์ชัน“ 1.41” ของไฟล์นั้นแตกต่างกัน

โดยทั่วไปแล้ว $ Id $ ไม่สมเหตุสมผลกับ Bazaar, Git และเครื่องมือจัดการซอร์สโค้ดแบบกระจายอื่น ๆ


6
ใช่ฉันอ่านก่อนที่จะโพสต์และนั่นคือเหตุผลที่ฉันขอวิธีแก้ปัญหาทั่วไปเพิ่มเติมสำหรับปัญหาพื้นฐาน ฉันคิดว่าความปรารถนาที่จะให้ไฟล์แต่ละไฟล์มีเวอร์ชัน # นั้นถูกต้องตามกฎหมายเนื่องจาก git ไม่สามารถให้โซลูชันได้
Joe Casadonte

ไม่ใช่ความสามารถของ Git แต่เป็น SCM แบบกระจายทั้งหมดไม่ได้ หากคุณต้องการหมายเลขเวอร์ชันที่มีความหมายจริงๆให้ใช้ Subversion หรือ CVS หรือระบบรวมศูนย์อื่น ๆ
Bombe

7
มีอะไรผิดปกติที่แค่คายแฮชออกมาแทนที่จะเป็น "หมายเลขเวอร์ชัน" ฉันต้องการคำสั่งบันทึกหน้าเว็บแก้ไขข้อบกพร่องและตัวเลือก "--version" บนสคริปต์ภายในที่จะบอกฉันได้อย่างง่ายดายว่าการแก้ไขกำลังทำงานอยู่ที่ใดดังนั้นฉันจึงสามารถเช็คเอาต์แฮชที่เฉพาะเจาะจงนั้นและดูว่าเหตุใดจึงทำงานได้อย่างที่เป็นอยู่ มันช่วยลดความยุ่งยากในการจัดการแอพที่ใช้งานได้ .... และฉันไม่ต้องการให้ hook กระทำบางตัวที่คิดว่าทุกการกระทำเป็นการเปลี่ยนแปลงไฟล์ทุกไฟล์ที่มีแท็ก $ Id $ อยู่ในนั้น
nairbv

1
แฮชของไฟล์ที่คุณกำลังทำงานอยู่จะใช้งานได้เหมือนกับ "เวอร์ชัน" ตราบใดที่คุณสามารถค้นหาใน git โดยใช้ id นั้น
Erik Aronesty

2
@ ไบรอัน - ตามการแก้ไขของ OP ผู้ใช้ต้องการทราบหมายเลขเวอร์ชัน แต่ไม่มีสิทธิ์เข้าถึงคอมไพล์หรือบันทึกคอมไพล์ ในกรณีนี้แฮชเป็นตัวเลขที่ไม่มีความหมายไม่ใช่หมายเลขเวอร์ชัน DSCM ไม่ให้ความช่วยเหลือในการแก้ไขความต้องการนี้
Jesse Chisholm

10

ผมมีปัญหาเหมือนกัน. ฉันจำเป็นต้องมีเวอร์ชันที่ง่ายกว่าสตริงแฮชและพร้อมใช้งานสำหรับผู้ที่ใช้เครื่องมือโดยไม่จำเป็นต้องเชื่อมต่อกับที่เก็บ

ฉันทำมันด้วยเบ็ดก่อนคอมมิตของ Git และเปลี่ยนสคริปต์ของฉันให้สามารถอัปเดตตัวเองโดยอัตโนมัติ

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

ตัวอย่างเช่นฉันมีสคริปต์ที่ฉันเช็คอินที่อยู่ใน Ruby และฉันเพิ่มรหัสนี้เข้าไป - มันเป็นรหัสที่ค่อนข้างง่ายดังนั้นจึงง่ายต่อการโอนไปยังภาษาต่างๆหากคุณกำลังเช็คอินในภาษาอื่น (แม้ว่าจะเห็นได้ชัดว่านี่ จะไม่ทำงานกับเช็คอินที่รันไม่ได้เช่นไฟล์ข้อความ) ฉันได้เพิ่ม:

MYVERSION = '1.090'
## Call script to do updateVersion from .git/hooks/pre-commit
def updateVersion
  # We add 1 because the next commit is probably one more - though this is a race
  commits = %x[git log #{$0} | grep '^commit ' | wc -l].to_i + 1
  vers = "1.%0.3d" % commits

  t = File.read($0)
  t.gsub!(/^MYVERSION = '(.*)'$/, "MYVERSION = '#{vers}'")
  bak = $0+'.bak'
  File.open(bak,'w') { |f| f.puts t }
  perm = File.stat($0).mode & 0xfff
  File.rename(bak,$0)
  File.chmod(perm,$0)
  exit
end

จากนั้นฉันเพิ่มตัวเลือกบรรทัดคำสั่ง (-updateVersion) ให้กับสคริปต์ดังนั้นถ้าฉันเรียกมันว่า "tool -updateVersion" มันก็แค่เรียก updateVersion สำหรับเครื่องมือที่แก้ไขค่า "MYVERSION" ในตัวมันเองแล้วออก (คุณสามารถ ให้อัปเดตไฟล์อื่น ๆ ด้วยหากเปิดเช่นกันหากคุณต้องการ)

เมื่อตั้งค่าเสร็จแล้วฉันไปที่ส่วนหัว Git และสร้างสคริปต์ทุบตีบรรทัดเดียวที่ปฏิบัติการได้ในไฟล์.git/hooks/pre-commit.

สคริปต์จะเปลี่ยนเป็นส่วนหัวของไดเร็กทอรี Git และเรียกสคริปต์ของฉันด้วย-updateVersion.

ทุกครั้งที่ฉันตรวจสอบในสคริปต์ก่อนการคอมมิตจะถูกรันซึ่งรันสคริปต์ของฉันด้วย -updateVersion จากนั้นตัวแปร MYVERSION จะได้รับการอัปเดตตามจำนวนคอมมิตที่จะเป็น มายากล!


ดังนั้นสคริปต์ Ruby ของคุณต้องเรียกว่า updateVersion git updateVersionหรือไม่? กรุณาใส่ตัวอย่างวิธีการเรียก
rjt

ฉันสร้างตัวเลือก (-updateVersion) ให้กับสคริปต์ที่ฉันกำลังเช็คอินซึ่งเรียกใช้ฟังก์ชัน 'updateVersion' (ในกรณีนี้ฉันกำลังพยายามเปลี่ยนหมายเลขเวอร์ชันในสคริปต์เอง) จากนั้นฉันก็สร้างคำสั่งเชลล์ oneliner ที่เรียกสคริปต์ของฉันด้วย -updateVersion จากนั้นจะอัปเดตตัวเองก่อนการเช็คอินทุกครั้ง
David Ljung Madison Stellar

8

หากการมี $ Keywords $ เป็นสิ่งจำเป็นสำหรับคุณคุณอาจลองดูMercurialแทน? มีส่วนขยาย hgkeyword ที่ใช้สิ่งที่คุณต้องการ Mercurial น่าสนใจในฐานะ DVCS อยู่แล้ว


8

สิ่งที่ทำกับที่เก็บ Git คือการใช้ไฟล์ tagวัตถุ สามารถใช้เพื่อแท็กคอมมิตด้วยสตริงประเภทใดก็ได้และสามารถใช้เพื่อทำเครื่องหมายเวอร์ชัน คุณสามารถดูแท็กนั้นในที่เก็บด้วยgit tagคำสั่งซึ่งส่งคืนแท็กทั้งหมด

ตรวจสอบแท็กได้ง่ายๆ ตัวอย่างเช่นหากมีแท็กv1.1คุณสามารถตรวจสอบแท็กนั้นไปยังสาขาได้ดังนี้:

git checkout -b v1.1

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

ไม่เพียงแค่นั้นแท็กยังคงมีอยู่แม้ว่าสาขาที่อยู่นั้นจะถูกลบไปแล้วโดยไม่ได้รวมกลับเข้าไปในบรรทัดหลักก็ตาม


6
มีวิธีทำให้แท็กนี้แทรกลงในไฟล์โดยอัตโนมัติโดย git หรือไม่? ขอบคุณ!
Joe Casadonte

1
หากคุณหมายถึงการขยายคำหลัก? ไม่เท่าที่ฉันรู้ หากคุณกำลังสร้างผลิตภัณฑ์คุณสามารถรับข้อมูลเป็นส่วนหนึ่งของสคริปต์การสร้างของคุณและแทรกลงในผลิตภัณฑ์ที่สร้างขึ้นของคุณ ลองใช้คำอธิบายของ man ซึ่งให้แท็กล่าสุดจำนวนคอมมิตตั้งแต่แท็กนี้และแฮชปัจจุบัน
Abizern

ใช่แท็กและข้อมูลที่เกี่ยวข้องอื่น ๆ สามารถแก้ไขลงในไฟล์โดยอัตโนมัติโดย git ผ่านexport-substคุณสมบัติของgitattributes(5). แน่นอนว่าต้องใช้git archiveเพื่อสร้างรีลีสและเฉพาะในไฟล์ tar ที่เป็นผลลัพธ์เท่านั้นที่จะมองเห็นการแก้ไขการแทนที่
Greg A. Woods

4

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

ก่อนอื่นให้รับการเปลี่ยนแปลงในจุดเริ่มต้นระยะไกล แต่อย่ารวมเข้ากับmasterสาขาของคุณ:

% git fetch

จากนั้นได้รับการเข้าสู่ระบบของการเปลี่ยนแปลงที่จะเกิดขึ้นในไฟล์ที่กำหนดระหว่างคุณสาขาและระยะไกลmasterorigin/master

% git log master..origin/master foo.el

สิ่งนี้จะให้ข้อความบันทึกของคอมมิตทั้งหมดที่เกิดขึ้นในที่เก็บระยะไกลนับตั้งแต่ที่คุณรวมorigin/masterเข้ากับmasterไฟล์.

wcถ้าคุณเพียงต้องการจำนวนการเปลี่ยนแปลงท่อไปยัง พูดดังนี้

% git rev-list master..origin/master foo.el | wc -l

1
ดังนั้นอย่าใช้ log: git rev-list master..origin / master | wc -l
Dustin

4

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

หากนั่นคือทั้งหมดที่คุณต้องการฉันจะหาวิธีระบุโดยไม่มีหมายเลขเวอร์ชัน

นอกจากนี้ฉันจะไม่รบกวนการเอื้อเฟื้อต่อใครเว้นแต่คุณจะแน่ใจว่าพวกเขาต้องการ :)


หากวันที่สามารถเปรียบเทียบได้ให้ใส่ DateTImeStamp ในไฟล์ git มีกรณีการใช้งานอื่น ๆ มากมายนอกเหนือจากนักพัฒนาซอฟต์แวร์ IT ในภาคสนามจำเป็นต้องทราบว่าไฟล์. INI หรือ. CONF บนเวิร์กสเตชันที่กำลังมีการแก้ไขปัญหาอยู่ใกล้กับสิ่งที่เป็นปัจจุบันหรือไม่
rjt

การประทับเวลาเพียงอย่างเดียวจะเพียงพอหรือไม่? สาขาที่ไม่ถูกต้องอาจมีการประทับเวลาที่น่าสนใจและยังคงถูกต้องน้อยกว่า
user2066657

4

หากต้องการใช้การขยายกับไฟล์ทั้งหมดในไดเร็กทอรีย่อยทั้งหมดในที่เก็บให้เพิ่ม.gitattributesไฟล์ลงในไดเร็กทอรีระดับบนสุดในที่เก็บ (เช่นที่คุณใส่.gitignoreไฟล์ตามปกติ) ที่มี:

* ident

เพื่อให้ได้ผลคุณจะต้องทำการชำระเงินที่มีประสิทธิภาพของไฟล์ก่อนเช่นลบหรือแก้ไขด้วยวิธีใด ๆ จากนั้นคืนค่าด้วย:

git checkout .

และคุณควรเห็น$Id$สิ่งที่ต้องการแทนที่:

$Id: ea701b0bb744c90c620f315e2438bc6b764cdb87 $

จากman gitattributes:

ident

เมื่อระบุแอตทริบิวต์สำหรับเส้นทาง Git จะแทนที่ $ Id $ ในวัตถุ blob ด้วย $ Id: ตามด้วยชื่อวัตถุหยดเลขฐานสิบหก 40 อักขระตามด้วยเครื่องหมายดอลลาร์ $ เมื่อชำระเงิน ลำดับไบต์ใด ๆ ที่ขึ้นต้นด้วย $ Id: และลงท้ายด้วย $ ในไฟล์ worktree จะถูกแทนที่ด้วย $ Id $ เมื่อเช็คอิน

รหัสนี้จะเปลี่ยนทุกครั้งที่มีการคอมมิตเวอร์ชันใหม่ของไฟล์


3

RCS ID นั้นดีสำหรับโปรเจ็กต์ไฟล์เดียว แต่สำหรับโปรเจ็กต์อื่น ๆ $ Id $ ไม่ได้บอกว่าไม่มีอะไรเกี่ยวกับโปรเจ็กต์ (เว้นแต่คุณจะบังคับให้เช็คอินจำลองเป็นไฟล์เวอร์ชันดัมมี่)

ยังคงมีคนสนใจว่าจะได้รับสิ่งที่เทียบเท่ากับ $ Author $, $ Date $, $ Revision $, $ RCSfile $ ฯลฯ ในระดับต่อไฟล์หรือในระดับการคอมมิต (วิธีการใส่คำหลักบางคำเป็นคำอื่น คำถาม). ฉันไม่มีคำตอบเกี่ยวกับสิ่งเหล่านี้ แต่ดูข้อกำหนดในการอัปเดตโดยเฉพาะอย่างยิ่งเมื่อไฟล์ (ตอนนี้อยู่ใน Git) มาจากระบบที่รองรับ RCS (CVS)

คำหลักดังกล่าวอาจน่าสนใจหากมีการแจกจ่ายแหล่งที่มาแยกต่างหากจากที่เก็บ Git ใด ๆ (นั่นคือสิ่งที่ฉันทำเช่นกัน) วิธีแก้ปัญหาของฉันเป็นดังนี้:

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

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

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


3

หากคุณต้องการให้ข้อมูลคอมมิตเข้าถึงในโค้ดของคุณคุณต้องทำขั้นตอนก่อนสร้างเพื่อไปที่นั่น ใน bash สำหรับ C / C ++ อาจมีลักษณะดังนี้:

prebuild.sh

#!/bin/bash
commit=$(git rev-parse HEAD)
tag=$(git describe --tags --always ${commit})
cat <<EOF >version.c
#include "version.h"
const char* git_tag="${tag}";
const char* git_commit="${commit}";
EOF

มีversion.hลักษณะดังนี้:

#pragma once
const char* git_tag;
const char* git_commit;

จากนั้นทุกที่ที่คุณต้องการในรหัส#include "version.h"และการอ้างอิงของคุณgit_tagหรือgit_commitตามความจำเป็น

และของคุณMakefileอาจมีสิ่งนี้:

all: package
version:
  ./prebuild.sh
package: version
  # the normal build stuff for your project

สิ่งนี้มีประโยชน์ดังนี้

  • รับค่าที่ถูกต้องในปัจจุบันสำหรับโครงสร้างนี้โดยไม่คำนึงถึงการแยกสาขาการรวมการเก็บเชอร์รี่และอื่น ๆ

การใช้งานนี้prepublish.shมีข้อเสียคือ:

  • บังคับให้คอมไพล์ใหม่แม้ว่าgit_tag/ git_commitไม่ได้เปลี่ยน
  • มันไม่ได้คำนึงถึงไฟล์ที่แก้ไขภายในเครื่องที่ไม่ได้ถูกคอมมิต แต่มีผลกับบิลด์
    • ใช้git describe --tags --always --dirtyจับกรณีการใช้งานนั้น
  • สร้างมลพิษให้กับเนมสเปซทั่วโลก

นักเล่นprebuild.shที่สามารถหลีกเลี่ยงปัญหาเหล่านี้ได้ถูกปล่อยให้เป็นแบบฝึกหัดสำหรับผู้อ่าน


1

ฉันเห็นด้วยกับผู้ที่คิดว่าการเปลี่ยนโทเค็นเป็นของเครื่องมือสร้างมากกว่าเครื่องมือควบคุมเวอร์ชัน

คุณควรมีเครื่องมือเผยแพร่อัตโนมัติเพื่อตั้งรหัสเวอร์ชันในแหล่งที่มาของคุณในขณะที่มีการแท็กรุ่น


2
.INI .conf และ. txt มักไม่มีเครื่องมือสร้าง
rjt

แต่คุณสามารถแฮ็กสคริปต์รุ่นที่ใช้แท็ก Git ปัจจุบันและเขียนลงในไฟล์หรือบางอย่างในการจัดเรียง
Marnen Laibow-Koser

1

ขณะนี้ชื่อแท็กและข้อมูลอื่น ๆ ที่เกี่ยวข้องสามารถแก้ไขลงในไฟล์ได้โดยตรงโดย Git ผ่านexport-substคุณสมบัติของgitattributes(5). แน่นอนว่าต้องใช้git archiveเพื่อสร้างรีลีสและเฉพาะในไฟล์ tar ที่เป็นผลลัพธ์เท่านั้นที่จะมองเห็นการแก้ไขการแทนที่

ตัวอย่างเช่นใน.gitattributesไฟล์ให้ใส่บรรทัดต่อไปนี้:

* export-subst

จากนั้นในไฟล์ต้นฉบับคุณสามารถเพิ่มบรรทัดดังนี้:

#ident  "@(#)PROJECTNAME:FILENAME:$Format:%D:%ci:%cN:%h$"

และจะขยายให้มีลักษณะเช่นนี้ในรุ่นที่สร้างโดยตัวอย่างเช่นgit archive v1.2.0.90:

#ident  "@(#)PROJECTNAME:FILENAME:HEAD -> master, tag: v1.2.0.90:2020-04-03 18:40:44 -0700:Greg A. Woods:e48f949"

0

เนื่องจากคุณใช้ Emacs คุณอาจโชคดี :)

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


0

ฉันมาจาก SCCS, RCS และ CVS ด้วย (%W% %G% %U% ) ด้วย

ฉันมีความท้าทายที่คล้ายกัน ฉันอยากรู้ว่าโค้ดชิ้นหนึ่งอยู่ในระบบใดที่รันอยู่ ระบบอาจเชื่อมต่อกับเครือข่ายใด ๆ หรือไม่ก็ได้ ระบบอาจติดตั้ง Git หรือไม่ก็ได้ ระบบอาจติดตั้งที่เก็บ GitHub หรือไม่ก็ได้

ฉันต้องการโซลูชันเดียวกันสำหรับโค้ดหลายประเภท (.sh, .go, .yml, .xml ฯลฯ ) ฉันต้องการให้บุคคลใดก็ตามที่ไม่มีความรู้เกี่ยวกับ Git หรือ GitHub สามารถตอบคำถามได้ "คุณกำลังใช้งานเวอร์ชันใดอยู่"

ฉันจึงเขียนสิ่งที่ฉันเรียกว่า wrapper รอบ ๆ คำสั่ง Git สองสามคำสั่ง ฉันใช้มันเพื่อทำเครื่องหมายไฟล์ด้วยหมายเลขเวอร์ชันและข้อมูลบางอย่าง มันช่วยแก้ปัญหาของฉันได้ มันอาจช่วยคุณได้

https://github.com/BradleyA/markit

git clone https://github.com/BradleyA/markit
cd markit

0

เพื่อแก้ไขปัญหานี้ด้วยตัวเองฉันได้สร้าง "แฮ็ก" ขนาดเล็กเป็นโพสต์คอมมิต hook:

echo | tee --append *
git checkout *

ในรายละเอียดการบันทึกไว้ในโพสต์นี้บนบล็อกของฉัน

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