Git สำหรับผู้ใช้ Perforce


86

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

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

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

  1. สร้างรายการการเปลี่ยนแปลงที่รอดำเนินการหลายรายการในไคลเอนต์เดียว ( p4 change)
  2. แก้ไขรายการการเปลี่ยนแปลงที่รอดำเนินการ (ยังp4 change)
  3. ดูรายการการเปลี่ยนแปลงที่รอดำเนินการทั้งหมดของฉัน ( p4 changes -s pending)
  4. รายการไฟล์ที่เปลี่ยนแปลงทั้งหมดในไคลเอนต์ของฉัน ( p4 opened) หรือในรายการการเปลี่ยนแปลงที่รอดำเนินการ ( p4 describe)
  5. ดูความแตกต่างของรายการการเปลี่ยนแปลงที่รอดำเนินการ (ฉันใช้สคริปต์ wrapper สำหรับสิ่งนี้ซึ่งใช้p4 diffและp4 describe)
  6. สำหรับไฟล์ที่ระบุให้ดูว่ารายการการเปลี่ยนแปลงที่ส่งส่งผลกระทบต่อบรรทัดใด ( p4 annotate)
  7. สำหรับไฟล์ที่ระบุดูรายการคำอธิบายของรายการการเปลี่ยนแปลงที่มีผลต่อไฟล์ (p4 log )
  8. ส่งรายการการเปลี่ยนแปลงที่รอดำเนินการ (p4 submit -c )
  9. ยกเลิกรายการการเปลี่ยนแปลงที่รอดำเนินการ ( p4 revert)

จำนวนมากวนเวียนอยู่กับ "รายการเปลี่ยนแปลง" "changelist" คือคำศัพท์ p4 คำศัพท์เทียบเท่า git คืออะไร?

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

อย่างไรก็ตาม ... ฉันไม่แน่ใจว่าจะทำสิ่งที่ฉันทำตามปกติในรายการการเปลี่ยนแปลง p4 ด้วยกิ่งก้านของ git ได้อย่างไร ใน p4 ฉันสามารถทำสิ่งนี้ได้:

$ p4 edit a.txt
$ p4 change a.txt
Change 12345 created.

ณ จุดนี้ฉันมีตัวเปลี่ยนที่มี a.txt ฉันสามารถแก้ไขคำอธิบายและทำงานต่อได้โดยไม่ต้องส่งรายการการเปลี่ยนแปลง นอกจากนี้หากปรากฎว่าฉันจำเป็นต้องทำการเปลี่ยนแปลงบางอย่างกับไฟล์อื่น ๆ เช่นพูดว่า bugfix ในเลเยอร์อื่น ๆ ของโค้ดฉันสามารถทำได้ในไคลเอนต์เดียวกัน:

$ p4 edit z.txt
$ p4 change z.txt
Change 12346 created.

ตอนนี้ฉันมีรายการการเปลี่ยนแปลงสองรายการแยกกันในไคลเอนต์เดียวกัน ฉันสามารถทำงานเหล่านี้ไปพร้อมกันได้และฉันไม่จำเป็นต้องทำอะไรเพื่อ "สลับไปมา" เมื่อถึงเวลาที่ต้องกระทำฉันสามารถส่งแยกกันได้:

$ p4 submit -c 12346  # this will submit the changes to z.txt
$ p4 submit -c 12345  # this will submit the changes to a.txt

ฉันคิดไม่ออกว่าจะจำลองสิ่งนี้ในคอมไพล์อย่างไร จากการทดลองของฉันไม่ปรากฏว่าgit addเกี่ยวข้องกับสาขาปัจจุบัน เท่าที่ฉันสามารถบอกได้เมื่อฉันgit commitจะคอมมิตไฟล์ทั้งหมดที่ I git add-ed ไม่ว่าฉันจะอยู่ในสาขาใดในเวลานั้น:

$ git init
Initialized empty Git repository in /home/laurence/git-playground/.git/
$ ls
a.txt  w.txt  z.txt
$ git add -A .
$ git commit
 Initial commit.
 3 files changed, 3 insertions(+), 0 deletions(-)
 create mode 100644 a.txt
 create mode 100644 w.txt
 create mode 100644 z.txt
$ vi a.txt z.txt 
2 files to edit
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   a.txt
#   modified:   z.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git branch aardvark
$ git checkout aardvark
M   a.txt
M   z.txt
Switched to branch 'aardvark'
$ git add a.txt 
$ git checkout master
M   a.txt
M   z.txt
Switched to branch 'master'
$ git branch zebra
$ git checkout zebra
M   a.txt
M   z.txt
Switched to branch 'zebra'
$ git add z.txt 
$ git status
# On branch zebra
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   a.txt
#   modified:   z.txt
#
$ git checkout aardvark
M   a.txt
M   z.txt
Switched to branch 'aardvark'
$ git status
# On branch aardvark
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   a.txt
#   modified:   z.txt

ในตัวอย่างนี้สาขา aardvark และ zebra ดูเหมือนจะมีชุดของการเปลี่ยนแปลงgit statusที่เหมือนกันทุกประการและจากผลลัพธ์ของมันดูเหมือนว่าการกระทำในข้อใดข้อหนึ่งจะมีผลเหมือนกัน ฉันทำอะไรผิดหรือเปล่า?


2
คุณสามารถใช้เพอร์ฟอร์ซสำหรับรหัสส่วนตัวของคุณโดยสมมติว่าลูกค้าฟรี 5 รายนั้นเพียงพอแล้ว
Logan Capaldo

3
นั่นคือสิ่งที่ฉันทำ แต่ฉันต้องการเปลี่ยนไปใช้สิ่งที่เป็นโอเพนซอร์สและใช้โดยโครงการโอเพนซอร์ส ฉันได้พิจารณาทั้ง git และ Mercurial ฉันเอนเอียงไปทางคอมไพล์เพราะดูเหมือนว่าจะมีโมเมนตัมมากกว่า
Laurence Gonsalves

1
คุณควรเรียนรู้ Git ตั้งแต่เริ่มต้นจะดีกว่า เวิร์กโฟลว์ที่กำหนดโดย Git แตกต่างอย่างมากกับเวิร์กโฟลว์ที่กำหนดโดย Perforce เวิร์กโฟลว์ที่แปลจะไม่สะดวกและการพยายามเปรียบคุณสมบัติจะทำให้ความเข้าใจของคุณสับสน โชคดีที่ชุมชน Git มีเอกสารมากมายสำหรับผู้เริ่มต้นเช่น git-scm.com/book
พันเอก Panic

1
@ColonelPanic ฉันเห็นประเด็นของคุณ แต่ปัญหาเกี่ยวกับเอกสารดังกล่าวคือการเสียเวลาอธิบายสิ่งพื้นฐานที่ผู้ใช้ Perforce ทุกคนรู้อยู่แล้ว การอ่านเอกสารดังกล่าวเป็นเรื่องที่น่ารำคาญพอ ๆ กับการพยายามอ่านบทช่วยสอนเกี่ยวกับภาษาโปรแกรมอื่นที่ใช้เวลาในการอธิบายว่าตัวแปรคืออะไร
Laurence Gonsalves

@ColonelPanic ที่กล่าวว่าฉันได้อ่านเอกสารคอมไพล์อื่น ๆ รวมถึงGit From the Bottom UpและGit สำหรับนักวิทยาศาสตร์คอมพิวเตอร์ซึ่งมีประโยชน์มาก ฉันใช้ Git มาสองสามปีแล้ว (สังเกตว่าเมื่อถามคำถามนี้ในตอนแรก) และฉันรู้สึกว่าปัญหาหลักในการเรียนรู้คอมไพล์ไม่ใช่การขาดเอกสาร แต่เป็นระบบการตั้งชื่อที่ไม่ดีความไม่สอดคล้องกันภายในคำสั่งที่มากเกินไปและบางอย่าง ชิ้นส่วนที่ยังไม่เสร็จซึ่งไม่พร้อมใช้งานจริง ฉันอยากให้ใครสักคนไปทำความสะอาดปมทั้งหมด แต่มันจะรบกวนคนที่เคยชินกับมัน
Laurence Gonsalves

คำตอบ:


72

ฉันไม่ได้ใช้ perforce มากนักดังนั้นนี่อาจไม่ใช่การแปล 1: 1 อย่างแน่นอน จากนั้นระบบควบคุมซอร์สแบบกระจายอีกครั้งเช่น git และ mercurial มีเวิร์กโฟลว์ที่แตกต่างกันดังนั้นจึงไม่มี (และไม่ควรมี) แปล 1: 1 อย่างไรก็ตามนี่ไป:

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

    git branch new-branch-name
    git checkout new-branch-name
    

    หรือทำทั้งหมดในบรรทัดเดียว:

    git checkout -b new-branch-name
    
  • ดูรายการการเปลี่ยนแปลงที่รอดำเนินการทั้งหมด -> เนื่องจากรายการการเปลี่ยนแปลงที่รอดำเนินการหลายรายการเทียบเท่ากับหลายสาขาเพียงแค่ดูสาขา:

    git branch
    

    หากคุณต้องการดูสาขาระยะไกลด้วย:

    git branch -a
    

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

  • แสดงรายการไฟล์ที่เปลี่ยนแปลงทั้งหมด -> สำหรับ "รายการการเปลี่ยนแปลง" ที่รอดำเนินการรายการเดียวในคอมไพล์สาขาเฉพาะมีแนวคิดเกี่ยวกับดัชนีหรือแคช ในการดำเนินการเปลี่ยนแปลงคุณต้องเพิ่มไฟล์ลงในดัชนีนี้ก่อน วิธีนี้ช่วยให้คุณสามารถเลือกกลุ่มไฟล์ที่แสดงถึงการเปลี่ยนแปลงครั้งเดียวด้วยตนเองหรือเพื่อละเว้นไฟล์ที่ไม่เกี่ยวข้อง หากต้องการดูสถานะว่าไฟล์ใดถูกเพิ่มหรือไม่ในดัชนีนี้ให้ทำดังนี้

    git status
    
  • ดูความแตกต่างของรายการการเปลี่ยนแปลงที่รอดำเนินการ -> มีสองส่วนนี้ ก่อนอื่นให้ดูความแตกต่างระหว่างไดเร็กทอรีการทำงานและดัชนี:

    git diff
    

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

    git diff HEAD
    
  • สำหรับไฟล์ที่ระบุให้ดูว่ารายการการเปลี่ยนแปลงที่ส่งมามีผลต่อบรรทัดใด -> ซึ่งง่ายมาก:

    git blame filename
    

    หรือดีกว่านั้นถ้าคุณอยู่ในสภาพแวดล้อมที่มีหน้าต่าง:

    git gui blame filename
    

    Git gui ใช้เวลาในการแยกวิเคราะห์ไฟล์นานกว่า (เขียนด้วย tcl แทน C) แต่มีคุณสมบัติที่เป็นระเบียบมากมายรวมถึงความสามารถในการ "ย้อนเวลา" ย้อนกลับไปในอดีตโดยคลิกที่รหัสการกระทำ ฉันเพียงหวังว่าพวกเขาจะใช้คุณลักษณะ "การเดินทางข้ามเวลา" ไปยังอนาคตเพื่อที่ฉันจะได้พบว่าในที่สุดข้อบกพร่องจะได้รับการแก้ไขอย่างไร ;-)

  • สำหรับไฟล์ที่ระบุให้ดูรายการคำอธิบายของรายการการเปลี่ยนแปลงที่ส่งผลกระทบต่อไฟล์ -> ง่ายเช่นกัน:

    git log filename
    

    แต่ git log เป็นเครื่องมือที่ทรงพลังกว่าแค่นี้ ในความเป็นจริงสคริปต์ส่วนตัวส่วนใหญ่ของฉัน piggyback off-of git log เพื่ออ่านที่เก็บ อ่านหน้าคน

  • ส่งรายการการเปลี่ยนแปลงที่รอดำเนินการ -> ง่ายเช่นกัน:

    git commit
    

ดูคำตอบของฉันสำหรับคำถามก่อนหน้านี้เพื่อดูขั้นตอนการทำงาน git ทั่วไปของฉัน: Learning Git ต้องการทราบว่าฉันมาถูกทางหรือไม่

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


คำตอบเพิ่มเติม:

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

git checkout -b new-feature-a

ตอนนี้คุณสามารถแก้ไขไฟล์ a.txt ในการทำงานพร้อมกันกับคุณสมบัติอื่นให้ทำ:

git checkout master
git checkout -b new-feature-z

ตอนนี้คุณสามารถแก้ไขไฟล์ z.txt ในการเปลี่ยนกลับเป็น a.txt:

git checkout new-feature-a

แต่เดี๋ยวก่อนมีการเปลี่ยนแปลงใน new-feature-z และ git จะไม่อนุญาตให้คุณเปลี่ยนสาขา ณ จุดนี้คุณมีสองทางเลือก อย่างแรกเป็นวิธีที่ง่ายที่สุดยอมรับการเปลี่ยนแปลงทั้งหมดกับสาขาปัจจุบัน:

git add .
git commit
git checkout new-feature-a

นี่คือสิ่งที่ฉันแนะนำ แต่ถ้าคุณไม่พร้อมที่จะยอมรับรหัสจริงๆคุณสามารถซ่อนไว้ชั่วคราว:

git stash

ตอนนี้คุณสามารถเปลี่ยนไปใช้ branch new-feature-a หากต้องการกลับไปที่รหัสที่คุณใช้งานอยู่เพียงแค่เปิดที่ซ่อน:

git checkout new-feature-z
git stash pop

เมื่อทุกอย่างเสร็จสิ้นให้ผสานกลับการเปลี่ยนแปลงทั้งหมดเป็นหลัก:

git merge --no-ff new-feature-a
git merge --no-ff new-feature-z

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

นี่คืออีกตัวอย่างหนึ่งของการใช้งาน Branch ในคอมไพล์ที่คุณไม่เห็นในเครื่องมือควบคุมแหล่งอื่น ๆ (ยกเว้น Mercurial):

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

git checkout -b dev-config

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

git add .
git commit

ตอนนี้ทุกสาขาใหม่สามารถเริ่มต้นจากสาขา dev-config แทน master:

git checkout dev-config
git checkout -b new-feature-branch

เมื่อคุณลบการแก้ไขใน dev-config จาก new-feature-branch โดยใช้ rebase แบบโต้ตอบ:

git rebase -i master

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

git checkout master
git merge --no-ff new-feature-branch
# because master have changed, it's a good idea to rebase dev-config:
git checkout dev-config
git rebase master

ควรสังเกตว่าการลบการแก้ไขgit rebase -iแม้จะใช้ได้ผลเมื่อการเปลี่ยนแปลงทั้งหมดเกิดขึ้นในไฟล์เดียวกัน Git จะจดจำการเปลี่ยนแปลงไม่ใช่เนื้อหาไฟล์ *

* หมายเหตุ: ในทางเทคนิคแล้วไม่เป็นความจริงทั้งหมด แต่ในฐานะผู้ใช้นั่นคือสิ่งที่รู้สึก


คำตอบเพิ่มเติมเพิ่มเติม:

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

ประการแรกคำที่เกี่ยวกับผลกระทบของการแยกสาขาราคาถูกและประวัติการแก้ไขในเวิร์กโฟลว์ของคุณ เมื่อฉันใช้ CVS และ SVN ฉันมักจะลังเลที่จะยอมรับ นั่นเป็นเพราะการส่งรหัสที่ไม่เสถียรจะทำให้รหัสการทำงานของคนอื่นลดลงอย่างหลีกเลี่ยงไม่ได้ แต่ด้วยคอมไพล์ฉันก็หายกลัว นั่นเป็นเพราะในคอมไพล์คนอื่นจะไม่ได้รับการเปลี่ยนแปลงของฉันจนกว่าฉันจะรวมพวกเขาให้เชี่ยวชาญ ตอนนี้ฉันพบว่าตัวเองกำลังป้อนรหัสทุกๆ 5 บรรทัดที่ฉันเขียน คุณไม่จำเป็นต้องมีการมองการณ์ไกลที่สมบูรณ์แบบในการกระทำ คุณเพียงแค่ต้องเปลี่ยนความคิดของคุณ: กระทำต่อสาขา == add-to-changeset, merge-to-master == คอมมิต - การเปลี่ยนแปลง

ดังนั้นกลับไปที่ตัวอย่าง นี่คือวิธีที่ฉันจะทำ สมมติว่าคุณมีสาขาและคุณต้องการที่จะทดสอบกับnew-feature-z new-feature-aฉันจะสร้างสาขาใหม่เพื่อทดสอบ:

# assume we are currently in branch new-feature-z
# branch off this branch for testing
git checkout -b feature-z-and-feature-a
# now temporarily merge new-feature-a
git merge --no-ff new-feature-a

ตอนนี้คุณสามารถทดสอบ หากคุณต้องการแก้ไขบางสิ่งบางอย่างเพื่อให้ feature-z ทำงานร่วมกับ feature-a ให้ทำเช่นนั้น หากเป็นเช่นนั้นคุณสามารถรวมการเปลี่ยนแปลงกลับไปยังสาขาที่เกี่ยวข้องได้ ใช้git rebase -iเพื่อลบการเปลี่ยนแปลงที่ไม่เกี่ยวข้องออกจากการผสาน

หรือคุณยังสามารถใช้ git rebase เพื่อเปลี่ยนฐานของ new-feature-z ชั่วคราวเพื่อชี้ไปที่ new-feature-a:

# assume we are currently in branch new-feature-z
git rebase new-feature-a

ตอนนี้ประวัติสาขาได้รับการแก้ไขเพื่อให้ new-feature-z ขึ้นอยู่กับ new-feature-a แทนที่จะเป็น master ตอนนี้คุณสามารถทดสอบ การเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นในสาขานี้จะเป็นของ branch new-feature-z หากคุณต้องการแก้ไขคุณลักษณะใหม่ - เพียงแค่เปลี่ยนกลับไปใช้และ rebase เพื่อรับการเปลี่ยนแปลงใหม่:

git checkout new-feature-a
# edit code, add, commit etc..
git checkout new-feature-z
git rebase new-feature-a
# now new-feature-z will contain new changes from new-feature-a

เมื่อคุณทำเสร็จแล้วเพียงแค่ rebase กลับไปที่ master เพื่อลบการเปลี่ยนแปลงจาก new-feature-a:

# assume we are currently in branch new-feature-z
git rebase master

อย่ากลัวที่จะเริ่มสาขาใหม่ อย่ากลัวที่จะเริ่มต้นสาขาที่ถูกทิ้งร้าง อย่ากลัวที่จะทิ้งกิ่งไม้ และตั้งแต่ผสาน == ส่งและคอมมิต == add-to-changeset อย่ากลัวที่จะคอมมิตบ่อยๆ จำไว้ว่าการกระทำเป็นเครื่องมือเลิกทำขั้นสูงสุดของนักพัฒนา

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


1
แต่ละสาขามี "ดัชนี" ของตัวเองหรือมีดัชนีเดียวที่ใช้ร่วมกันระหว่างสาขา? การทดลองของฉันดูเหมือนจะแนะนำอย่างหลัง แต่คุณพูดว่า "git สาขาเฉพาะมีแนวคิดเกี่ยวกับดัชนีหรือแคช" ซึ่งแนะนำอดีต
Laurence Gonsalves

4
มันเป็นเครื่องมือที่แตกต่างกัน คุณต้องการขั้นตอนการทำงานที่แตกต่างกันและด้วยความคิดและนิสัยที่แตกต่างกัน ไม่มีคอมไพล์ไม่ได้ผลตามที่คุณอธิบาย มันเป็นสาขาและไม่มีอะไรอื่น แต่มีเครื่องมือจัดการสาขาที่มีประสิทธิภาพมาก ฉันขอแนะนำให้คุณถือว่าคุณเป็นมือใหม่ที่ไม่รู้อะไรเลยเกี่ยวกับการควบคุมแหล่งที่มาและอ่านบทช่วยสอนพื้นฐาน ลองพิจารณาความคิดในปัจจุบันของคุณว่า "นิสัยเสีย" ที่คุณต้องได้รับการศึกษาใหม่ในเรื่อง git-land ขออภัย ..
slebetman

1
คุณจะทำอย่างไรในการคอมไพล์เมื่อคุณมีสองสิ่งที่คุณต้องการทำงานพร้อมกัน (และในที่เดียวกันเพื่อให้คุณสามารถทดสอบการเปลี่ยนแปลงที่ไม่ได้ผูกมัดซึ่งกันและกัน) แต่คุณต้องการที่จะยืนยันแยกกัน? นอกจากนี้คุณจะแก้ไขข้อความคอมมิตก่อนดำเนินการคอมมิตได้อย่างไร? ฉันยอมรับว่าเวิร์กโฟลว์แตกต่างกัน แต่คุณไม่ได้บอกว่าเวิร์กโฟลว์เทียบเท่าคอมไพล์คืออะไร การบอกว่าสิ่งเหล่านี้เป็นนิสัยที่ไม่ดีฟังดูแย่มากเช่นการพยายามที่จะตัดข้อบกพร่องเป็นคุณลักษณะ
Laurence Gonsalves

2
อ่านคำตอบที่อัปเดตของฉัน คุณยังคงคิดในแง่ของการเปลี่ยนแปลงที่ไม่ได้ผูกมัดเมื่อคุณควรคิดถึงสาขาที่ยังไม่ได้ผสาน
slebetman

2
คำตอบที่กว้างขวางมาก สิ่งนี้ควรจะถูกวิกิพีเดียในจุดใด?
Tim Clemons

1

ฉันไม่มีประสบการณ์ p4 เพียงพอที่จะสร้างแผ่นโกงจริง แต่อย่างน้อยก็มีความคล้ายคลึงกันอยู่บ้าง p4 "changeset" คือคอมไพล์ "คอมมิต"

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

คุณมองไปที่การเปลี่ยนแปลงด้วยgit diffและgit statusที่git diffมักจะแสดงให้เห็นถึงการเปลี่ยนแปลงระหว่างพื้นที่ทำงานและดัชนี แต่git diff --cachedแสดงให้เห็นว่าการเปลี่ยนแปลงระหว่างดัชนีและพื้นที่เก็บข้อมูล (= รายการการเปลี่ยนแปลงที่รอดำเนินการของคุณ)

สำหรับข้อมูลเพิ่มเติมข้อมูลเชิงลึกผมขอแนะนำให้http://progit.org/book/ เนื่องจากคุณรู้จักการควบคุมเวอร์ชันโดยทั่วไปคุณจึงสามารถอ่านข้อมูลจำนวนมากและดึงข้อมูลเฉพาะของคอมไพล์ได้ ...


1
ฉันไม่เห็นด้วยที่ "ชุดการเปลี่ยนแปลง p4 เป็นการคอมมิตคอมมิต"; พวกมันใกล้เคียงที่สุดจริง แต่ชุดการเปลี่ยนแปลง p4 นั้นใกล้เคียงกับชุดคอมมิตคอมมาก ชุดการเปลี่ยนแปลง p4 แสดงถึงคุณลักษณะในขณะที่ git branch แสดงถึงคุณลักษณะ
RJFalconer

@RJFalconer เอิ่ม. "สาขา" ก็คือสาขาใน Perforce ด้วยใช่หรือไม่? และ "ชุดการเปลี่ยนแปลง" คือชุดอะตอมของการเปลี่ยนแปลงไฟล์อย่างน้อยหนึ่งไฟล์เหมือนกับการคอมมิตหรือไม่? ถ้าไม่คุณจะบอกว่าอะไรคือ p4 เทียบเท่ากับการกระทำ?
Jakob Borg

ฉันจะบอกว่า p4 ไม่เทียบเท่าเพียงเพราะระดับของอะตอมไม่เท่ากัน ในคอมไพล์ฉันสามารถทำการเปลี่ยนแปลงหลายอย่างในไฟล์ที่กำหนดจากนั้นทำการคอมมิตในคอมมิตที่แตกต่างกัน (git add -p) ดังนั้นจึงแยกการปรับโครงสร้าง / ล้างข้อมูลในประวัติออกจากฟีเจอร์ / การแก้ไขข้อบกพร่อง ถ้าฉันจะทำใน p4 ฉันจะต้องพัฒนาทั้งสองอย่างแยกกัน แม้ว่าการกระทำของฉันอาจไม่ต่อเนื่องเนื่องจากนักพัฒนารายอื่นสามารถส่งระหว่างกันได้ (เว้นแต่ฉันจะเป็นสาขาส่วนตัวซึ่งเกี่ยวข้องกับการทำซ้ำบนดิสก์ที่ไม่สามารถทำได้)
RJFalconer

ข้อจำกัดความรับผิดชอบ: ฉันใช้ p4 เพียงไม่กี่เดือนและค่อนข้างเป็นไปได้ว่ามีคุณสมบัติบางอย่างที่ทำสิ่งนี้ได้สำเร็จซึ่งฉันยังไม่เคยเจอ
RJFalconer

p4 changelists และ p4 branch มีเหตุผลเหมือนกับ git commits และ git branch p4 Shelve เทียบเท่ากับ git stash จุดที่แตกต่างกันคือในการนำไปใช้งาน (เช่นกระจายกับไคลเอนต์เซิร์ฟเวอร์) และความแตกต่างนั้นส่งผลให้ p4 เทียบเท่ากับการชำระเงิน git ที่เกี่ยวข้องกับหลายขั้นตอนและเวลาที่มาก ค่าโสหุ้ยเป็นเช่นนั้นโดยทั่วไปแล้วสาขาต่างๆจะถูกเก็บรักษาไว้ในดิสก์แทนที่จะทำเช่นเดียวกับการชำระเงิน git ชั้นวาง p4 ถูกเก็บไว้บนเซิร์ฟเวอร์แทนที่จะอยู่ใน repo ในเครื่อง
Josh Heitzman

1

ฉันต้องทนทุกข์ทรมานเช่นเดียวกับคุณที่ขาดแนวคิด "รายการเปลี่ยนแปลง" ซึ่งไม่เหมือนกับสาขาคอมไพล์ทุกประการ

ฉันจะเขียนสคริปต์เล็ก ๆ ที่จะสร้างไฟล์รายการการเปลี่ยนแปลงพร้อมรายชื่อไฟล์ในรายการการเปลี่ยนแปลงนั้น

คำสั่งอื่นในการส่งรายการการเปลี่ยนแปลงบางรายการโดยเพียงแค่เรียกคอมมิต -a @ change_list_contents.txt จากนั้น "คอมมิตคอมมิต"

หวังว่าจะช่วยได้ Elias


ใช่ฉันเคยคิดจะทำอะไรแบบนี้ แต่ในตอนที่ฉันถามคำถามนี้ฉันยังใหม่กับคอมไพล์และฉันก็เลยอยากรู้วิธีแก้ปัญหาแบบ "เนทีฟ" ตอนนี้ฉันพบว่าสิ่งสำคัญที่ฉันพลาดคือความสามารถในการทำงานกับข้อความคอมมิทโดยไม่ต้องกระทำจริงๆ ดังนั้นจึงสามารถแก้ไขได้โดยการมีไฟล์เพื่อเก็บ "ข้อความที่รอดำเนินการ" และอาจมีเวทมนตร์บางอย่างที่จะอ่านโดยอัตโนมัติเมื่อเขียนข้อความคอมมิต
Laurence Gonsalves

@LaurenceGonsalves เวิร์กโฟลว์ที่ฉันใช้คือการส่งข้อความคอมมิตที่ไม่สมบูรณ์ (หรือแม้แต่ "WIP") ในขณะที่ฉันจดจ่ออยู่กับงานจากนั้นแก้ไขภายหลังในระหว่างการปรับฐาน เนื่องจากการคอมมิตเป็นแบบท้องถิ่นเท่านั้นจึงไม่จำเป็นต้องถือเป็นขั้นสุดท้ายจนกว่าคุณจะทำให้สาขาของคุณพร้อมใช้งาน (โดยการกดไปที่รีโมตหรือสิ่งที่คล้ายกันของคุณ)
RJFalconer

1

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

ฉันมักจะทำการเปลี่ยนแปลงจากนั้นส่งคอมมิตหลาย ๆ อย่าง (เช่นเพิ่มคำสั่ง debug, refactor, แก้ไขจุดบกพร่อง) แทนที่จะตั้งค่า perforce changelists ของคุณจากนั้นทำการเปลี่ยนแปลงจากนั้นจึงส่งคุณสามารถทำการเปลี่ยนแปลงได้จากนั้นเลือกวิธีการส่ง (เลือกได้โดยใช้พื้นที่ git staging)

คุณสามารถคอมมิตไฟล์เฉพาะจากบรรทัดคำสั่งด้วย:

git commit a.txt
git commit z.txt

หรือจัดเตรียมไฟล์อย่างชัดเจนก่อน:

git add a.txt
git commit
git add z.txt
git commit

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

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


เป็นความจริงอย่างแน่นอนที่คอมไพล์ช่วยให้คุณสามารถทำการคอมมิตที่ละเอียดกว่าเพอร์ฟอร์ซ (เช่น: เส้นและฮังค์) สิ่งที่ฉัน (ยัง) พลาดจาก perforce คือความสามารถในการติดตามคำอธิบายการเปลี่ยนแปลง (หรือที่เรียกว่าข้อความกระทำ) สำหรับสิ่งที่ฉันกำลังทำ ตัวอย่างเช่นเมื่อฉันจะแก้ไขข้อผิดพลาด # 12345 ฉันจะสร้างรายการการเปลี่ยนแปลงโดยบอกว่าฉันกำลังทำสิ่งนั้นอยู่ (แต่ไม่ต้องส่งหรือที่ยอมรับมัน) จากนั้นขณะที่ดำเนินการนี้ฉันจะอัปเดตคำอธิบายการเปลี่ยนแปลงเพื่อระบุสิ่งที่ฉันทำ ในที่สุดเมื่อฉันทำเสร็จฉันจะยอมรับรายการการเปลี่ยนแปลง
Laurence Gonsalves

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

@LaurenceGonsalves อยากรู้อยากเห็นถ้าคุณเคยชินกับมันในระหว่างนี้ ฉันมาที่ Perforce จาก Git และฉันพลาดที่จะคอมมิตทุก ๆ 15 นาทีแล้วกดเมื่อฉันพร้อม
damian

0

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

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


2
นั่นคือสิ่งที่ฉันทำ แต่ฉันต้องการเปลี่ยนไปใช้สิ่งที่เป็นโอเพนซอร์สและใช้โดยโครงการโอเพนซอร์ส
Laurence Gonsalves

0

เมื่อใช้ทั้ง Perforce และ git อย่างกว้างขวางแล้วมีเพียงวิธีเดียวที่ฉันสามารถมองเห็นได้ว่าจะไปที่ไหนก็ได้ใกล้กับรายการเปลี่ยนแปลงของ Perforce ด้วยคอมไพล์

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

Perforce changelists อนุญาตให้มีเวิร์กโฟลว์ที่ไม่มีคอมไพล์เทียบเท่า พิจารณาขั้นตอนการทำงานต่อไปนี้:

Check out a branch
Modify file A and add it to changelist 1
Modify file B and add it to changelist 2

หากคุณพยายามทำสิ่งนี้โดยใช้ branch ใน git คุณจะได้รับสองสาขาซึ่งหนึ่งในนั้นมีการเปลี่ยนแปลงไฟล์Aอีกอันมีการเปลี่ยนแปลงไฟล์Bแต่ไม่มีที่ใดที่คุณจะเห็นการเปลี่ยนแปลงของไฟล์ทั้งสองAและBที่ ในเวลาเดียวกัน.

ประมาณใกล้เคียงที่สุดที่ฉันสามารถมองเห็นคือการใช้git add . -pแล้วใช้'a'และ'd'ย่อยคำสั่งเพื่อเลือกหรือปฏิเสธไฟล์ทั้งหมด อย่างไรก็ตามมันไม่เหมือนกันซะทีเดียวและความแตกต่างที่นี่เกิดจากความไม่เท่าเทียมกันพื้นฐานในตัวดำเนินการแบบทั่วไปของทั้งสองระบบ

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


0

ด้วย Git 2.27 (Q2 2020) " git p4" ได้เรียนรู้สี่ hooks ใหม่และ--no-verifyตัวเลือก "" ในการข้าม (และp4-pre-submithook " " ที่มีอยู่)

ดูกระทำ 1ec4a0a , กระทำ 38ecf75 , กระทำ cd1e0dc (14 กุมภาพันธ์ 2020) และกระทำ 4935c45 , กระทำ aa8b766 , กระทำ 9f59ca4 , กระทำ 6b602a2 (11 กุมภาพันธ์ 2020) โดยเบนคีน (seraphire )
(รวมโดยJunio C Hamano - gitster-ในการกระทำ 5f2ec21 , 22 เมษายน 2020)

git-p4: เพิ่ม p4 ส่ง hooks

ลงนามโดย: Ben Keene

คำสั่ง git " commit" สนับสนุน hooks จำนวนมากที่รองรับการเปลี่ยนแปลงลักษณะการทำงานของคำสั่งคอมมิต

git-p4.pyโปรแกรมมีเพียงหนึ่งเบ็ดที่มีอยู่ " p4-pre-submit"

คำสั่งนี้เกิดขึ้นในช่วงแรกของกระบวนการ

ไม่มี hooks ในโฟลว์กระบวนการสำหรับการปรับเปลี่ยนข้อความการเปลี่ยนแปลง P4 โดยทางโปรแกรม

เพิ่ม 3 hooks ใหม่git-p4.pyในตัวเลือกส่ง

ตะขอใหม่คือ:

  • p4-prepare-changelist- ดำเนินการเบ็ดนี้หลังจากสร้างไฟล์รายการการเปลี่ยนแปลงแล้ว
    เบ็ดจะถูกดำเนินการแม้ว่า--prepare-p4-onlyจะตั้งค่าตัวเลือกไว้ก็ตาม
    เบ็ดนี้ละเว้นตัวเลือกในการรักษาด้วยพฤติกรรมที่มีอยู่ของ--no-verifygit commit

  • p4-changelist- ดำเนินการเบ็ดนี้หลังจากผู้ใช้แก้ไขรายการการเปลี่ยนแปลง
    อย่าดำเนินการเบ็ดนี้หากผู้ใช้เลือก--prepare-p4-onlyตัวเลือก
    เบ็ดนี้จะให้เกียรติ--no-verifyตามอนุสัญญาของgit commit.

  • p4-post-changelist- ดำเนินการเบ็ดนี้หลังจากกระบวนการส่ง P4 เสร็จสมบูรณ์
    เบ็ดนี้ไม่ใช้พารามิเตอร์และถูกดำเนินการโดยไม่คำนึงถึง--no-verifyตัวเลือก

ค่าส่งคืนจะไม่ถูกตรวจสอบ

การเรียกไปยัง hooks ใหม่: p4-prepare-changelist, p4-changelistและp4-post-changelistควรเรียกทั้งหมดภายในบล็อก try-last


ก่อน Git 2.28 (ไตรมาสที่ 3 ปี 2020) --prepare-p4-onlyตัวเลือก "" ควรจะหยุดหลังจากเล่นชุดการเปลี่ยนแปลงซ้ำ แต่ยังคงดำเนินต่อไป (โดยไม่ได้ตั้งใจ?)

ดูกระทำ 2dfdd70 (12 พฤษภาคม 2020) โดยเบนคีน (seraphire )
(รวมโดยJunio C Hamano - gitster-ในการกระทำ 7a8fec9 , 2 มิถุนายน 2020)

git-p4.py: แก้ไข--prepare-p4-onlyข้อผิดพลาดด้วยการกระทำหลายครั้ง

ลงนามโดย: Ben Keene

เมื่อใช้git p4 submitกับ--prepare-p4-onlyตัวเลือกนี้โปรแกรมควรจัดเตรียมรายการการเปลี่ยนแปลง p4 รายการเดียวและแจ้งให้ผู้ใช้ทราบว่ามีการดำเนินการเพิ่มเติมที่รอดำเนินการจากนั้นจึงหยุดการประมวลผล

ข้อบกพร่องได้รับการแนะนำโดยp4-changelistคุณลักษณะ hook ซึ่งทำให้โปรแกรมพยายามดำเนินการต่อและดำเนินการกับรายการการเปลี่ยนแปลงที่รอดำเนินการทั้งหมดในเวลาเดียวกัน

ฟังก์ชันapplyCommitจะส่งคืนTrueเมื่อใช้การกระทำสำเร็จและโปรแกรมควรดำเนินการต่อ
อย่างไรก็ตามเมื่อตั้งค่าสถานะทางเลือก--prepare-p4-onlyโปรแกรมควรหยุดหลังจากแอ็พพลิเคชันแรก

เปลี่ยนตรรกะในวิธีการรันสำหรับ P4Submit เพื่อตรวจสอบแฟล็ก--prepare-p4-onlyหลังจากทำapplyCommitเมธอดสำเร็จ

หากมากกว่า 1 คอมมิตอยู่ระหว่างการส่งไปยัง P4 เมธอดจะเตรียมรายการการเปลี่ยนแปลง P4 อย่างถูกต้องอย่างไรก็ตามจะยังคงออกจากแอปพลิเคชันโดยมีรหัสออกเป็น 1

เอกสารปัจจุบันไม่ได้กำหนดสิ่งที่รหัสทางออกควรจะอยู่ในสภาพนี้

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