2 คะแนน โดย GN⁺ 15 일 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • jj ซึ่งเป็น อินเทอร์เฟซบรรทัดคำสั่ง ของ Jujutsu เป็นเครื่องมือที่ทำงานบนพื้นฐานของ ระบบควบคุมเวอร์ชันแบบกระจาย (DVCS)
  • มอบ ความสามารถที่เรียบง่ายและเข้าใจได้ง่ายกว่า git แต่ทรงพลังกว่า
  • ผสานข้อดีของ git และ Mercurial เพื่อลดจำนวนเครื่องมือแกนหลักและเสริมการทำงานร่วมกันอย่างเป็นธรรมชาติ
  • ใช้ แบ็กเอนด์ที่เข้ากันได้กับ git ทำให้สามารถทดลองใช้งานอย่างอิสระได้โดยยังคงสภาพแวดล้อมการทำงานร่วมกันเดิมไว้
  • สำหรับผู้ใช้ระดับสูง จุดสำคัญคือสามารถใช้ ความสามารถด้านการจัดการเวอร์ชันเพิ่มเติม ที่ทำได้ยากใน git

แนะนำและจุดเด่นของ jj

  • jj คือ CLI (อินเทอร์เฟซบรรทัดคำสั่ง) ของ Jujutsu โดย Jujutsu เป็นระบบควบคุมเวอร์ชันแบบกระจาย (DVCS)

    • ผู้ใช้อาจคุ้นเคยกับ DVCS อื่นอย่าง git และบทช่วยสอนนี้ตั้งอยู่บนมุมมองของผู้ใช้ git
    • jj ถูกออกแบบให้เป็น เครื่องมือที่เรียบง่าย ใช้งานง่ายกว่า git แต่ยังทรงพลัง
    • โดยทั่วไป “ความทรงพลัง” กับ “ความซับซ้อน” มักขัดแย้งกัน แต่ jj นำเสนอสมดุลนี้ในรูปแบบใหม่
    • jj รวมข้อดีของ git และ Mercurial(hg) เพื่อสร้าง DVCS รูปแบบใหม่
    • ลดจำนวนเครื่องมือแกนหลัก และมอบสภาพแวดล้อมการทำงานที่มีประสิทธิภาพผ่าน การทำงานร่วมกันอย่างเป็นธรรมชาติ ระหว่างแต่ละเครื่องมือ
    • ผู้ใช้ระดับสูงสามารถใช้ ความสามารถด้านการจัดการเวอร์ชันเพิ่มเติม ที่ทำได้ยากใน git
    • jj ใช้ แบ็กเอนด์ที่เข้ากันได้กับ git จึงสามารถทดลองใช้งานได้อย่างอิสระโดยไม่ต้องเปลี่ยนสภาพแวดล้อมการทำงานร่วมกัน
    • ยังคงความเข้ากันได้กับที่เก็บข้อมูล git เดิม และหากจำเป็นก็สามารถกลับไปใช้ git ได้อย่างง่ายดาย
    • บทช่วยสอนจะพาไปดูโดยตรงผ่านคุณสมบัติเหล่านี้ว่า jj เป็นเครื่องมือที่น่าจับตามองเพราะอะไร

1 ความคิดเห็น

 
GN⁺ 15 일 전
ความคิดเห็นจาก Hacker News
  • แม้ว่าการถกเถียงจำนวนมากจะมุ่งไปที่ ความแตกต่างระหว่าง git กับ jj แต่ฉันคิดว่าควรลืม git ไปก่อนแล้วโฟกัสกับเวิร์กโฟลว์พื้นฐานของ jj จะดีกว่า
    ถ้ารัน jj ในรีโพที่สะอาด ก็สามารถดูสถานะได้ และหลังจากแก้ไขแล้วก็แค่คอมมิตด้วย jj commit -m "made changes"
    ถ้าพลาด ก็แก้ให้ถูกแล้วใช้ jj squash เพื่อรวมเข้ากับคอมมิตล่าสุด
    ใช้ jj new -r lmnop เฉพาะเวลาที่อยากทำงานจากรีวิชันหนึ่งแบบเป็นสาขาใหม่
    ดูประวัติ git ได้ด้วย git log และจะไม่เห็นกลไกภายในของ jj

    • ฉันก็อยากได้อะไรประมาณนั้นเหมือนกัน เลยทำ git alias อย่าง alias.save="!git add -A; git commit -m" แล้วใช้เป็น $ git save "made changes"
  • JJ ให้ความรู้สึกเหมือนบังคับให้ฉัน คิดย้อนกลับ
    ใน git เราแก้ก่อนแล้วค่อยเขียนข้อความคอมมิต แต่ jj เหมือนสร้างคอมมิตใหม่ก่อนแล้วค่อยใส่คำอธิบาย
    ฉันคุ้นกับการเลือกเฉพาะส่วนที่ต้องการจากสถานะรก ๆ ที่มีหลายฟีเจอร์ปนกันแล้วค่อยคอมมิต แต่ดูจากแค่ทิวทอเรียลของ jj ยังไม่แน่ใจว่าทำแบบนั้นได้ไหม

    • jj new คือแนวคิดที่คล้ายกับ git staging area ที่ว่างเปล่า
      ใน jj จะมีคอมมิตอยู่เสมอ และคอมมิตนั้นมี changeid ที่เสถียร ซึ่งคำนวณจากเนื้อหาในโฟลเดอร์
      ถ้าอยากแยกหลายการเปลี่ยนแปลงออกเป็นหลายคอมมิต ก็ใช้ jj split
    • ฉันมักใช้ jj new เพื่อสร้างคอมมิตชั่วคราวและปล่อยข้อความว่างไว้
      พอพร้อมแล้วค่อย squash หลายคอมมิตรวมเป็นหนึ่งแล้วเพิ่มข้อความ
      วิธีนี้ทำงานคล้าย ประวัติการ undo เลยทำให้ทดลองอะไรได้สะดวกกว่ามาก
    • จริง ๆ แล้ว jj new ก็แค่ “สร้างคอมมิตใหม่ไว้ข้างบน” เท่านั้นเอง เลยไม่จำเป็นต้องเขียนคำอธิบายทันที
      ตอนแรกฉันก็พยายามฝึกให้เป็นนิสัย แต่กลับไม่มีประสิทธิภาพ
    • ใน JJ วิธีนี้ถือว่า เป็นมาตรฐาน
      ฝั่ง Git ก็แนะนำเวิร์กโฟลว์คล้ายกันมานานแล้ว และดู Squash Workflow ได้ถ้าอยากได้การไหลงานที่คล้ายกับ index ของ Git
    • เวลาฉันทำหลายอย่างพร้อมกัน มักมีฟีเจอร์ต่าง ๆ ปนกันไปหมด
      เลยมีหลาย workspace และใช้ฟังก์ชัน shelve ของ IntelliJ บ่อยมาก
      บางทีก็เก็บ diff ชั่วคราวไว้เป็น git patch
      แล้วก็พยายามซ่อนกระบวนการที่วุ่นวายพวกนี้จากเพื่อนร่วมงานเพื่อให้ดู เป็นมืออาชีพ มากขึ้นนิดหน่อย
  • พอลองใช้ jj แล้ว สิ่งที่ไม่ชอบคือการแก้ไฟล์จะถูกคอมมิตโดยอัตโนมัติ
    ถ้า checkout ไปดูคอมมิตเก่าแล้วแก้ไฟล์ คอมมิตนั้นจะถูกเปลี่ยนและประวัติถัดจากนั้นทั้งหมดจะถูก rebase ใหม่
    เลยต้องสร้างคอมมิตว่างไว้ก่อนแบบป้องกันตัว
    git สะดวกกว่าสำหรับฉันเพราะรีโพจะไม่เปลี่ยนจนกว่าจะคอมมิตอย่างชัดเจน

    • เมื่อก่อนฉันก็คิดแบบนั้น แต่เปลี่ยนใจหลังจากรู้จัก jj evolog
      jj มีทางออกที่ดีกว่า staging อยู่แล้ว
      ความคุ้นชินกับ git CLI กลับกลายเป็น อุปสรรค ต่อการเรียนรู้ jj
      ที่น่าสนใจคือพอใช้ jj แล้วจะเข้าใจ โครงสร้างของ storage engine ของ git ดีขึ้นด้วย
    • ถ้าใช้ jj new แทน edit ก็จะติดตามการเปลี่ยนแปลงได้อย่างสะอาด
      รู้สึกว่าดีกว่าการคอย juggling กับ stash ของ git มาก
    • jj edit คือ กับดักที่ใหญ่ที่สุด ของ jj
      ควรใช้ jj new แทน และถ้าพลาดก็สามารถกู้กลับด้วย jj undo
      jj มองคอมมิตเป็น snapshot ราคาถูก จึงควรโฟกัสที่ “การเปลี่ยนแปลง” มากกว่าตัวคอมมิต
      auto rebase จะถูกตรึงให้ไม่เปลี่ยนหลัง push แล้ว จึงปลอดภัย
    • การที่การแก้ไฟล์ถูกคอมมิตอัตโนมัติคือ ฟีเจอร์หลัก ของ jj
      แค่ใช้ jj new กับ jj squash ร่วมกันเพื่อจัดการเหมือน branch head ของ git ก็พอ
      jj ทำให้การทำงานในสถานะ detached head เป็นเรื่องง่าย
    • น่าจะเป็นเพราะคุณ checkout คอมมิตเก่าด้วย jj edit
      ถ้าเปลี่ยนไปใช้ jj new ปัญหานี้ก็จะหายไป
  • ย่อหน้าสุดท้ายของ jj คือประเด็นสำคัญ
    เพราะมันใช้แบ็กเอนด์ที่ เข้ากันได้กับ git อย่างสมบูรณ์ คุณจึงลองใช้คนเดียวได้โดยไม่ต้องให้ทั้งทีมเปลี่ยน
    ถ้าไม่ชอบก็กลับไปใช้ git ได้ทุกเมื่อ

    • ยกเว้นในองค์กรที่ใช้ LFS, submodule หรือ hook
    • ไม่ได้เข้ากันได้อย่างสมบูรณ์จริง ๆ เป็นการทำงานร่วมกันได้ แต่ ไม่ได้ลื่นไหลไร้รอยต่อแบบสมบูรณ์
      การทำงานฝั่ง git จะไม่ถูกบันทึกในล็อกของ jj จึงต้อง import เองด้วยมือ
      ในโปรเจกต์หนึ่งควรใช้แค่อินเทอร์เฟซเดียว
    • เมื่อก่อนฉันก็ใช้ git แบบนั้นร่วมกับ CVS และ Subversion
    • แต่ถ้าใช้ git กับ jj พร้อมกันในไดเรกทอรีเดียวกัน มันอาจพังได้
  • ฟีเจอร์ที่ฉันชอบที่สุดคือ jj absorb
    มันย้ายการเปลี่ยนแปลงในรีวิชันปัจจุบันกลับไปยังคอมมิตก่อนหน้าที่เกี่ยวข้องให้อัตโนมัติ
    มีประโยชน์มากเวลาลืมแก้ไฟล์ตั้งค่า หรือ .gitignore
    แค่ jj new แล้วแก้ จากนั้น jj absorb
    ที่ดีที่สุดคือไม่ต้องจัดการ merge conflict

    • ถ้า jj absorb ใช้ผิด ก็ย้อนกลับได้ด้วย jj undo
      ฟีเจอร์นี้ทำให้ไม่ต้องกลัว rebase ซับซ้อนอีกต่อไป
    • อ้างอิงไว้ก่อนว่าใน git ก็มี git absorb เหมือนกัน
  • ฉันไม่ได้อัปเดตทิวทอเรียลมานานแล้ว แต่ก็ยังใช้ jj ทุกวันอยู่
    ช่วงนี้ยุ่งกับสตาร์ตอัป ersc.io เลยไม่ได้ทำงาน upstream
    ถ้ามีคำถามก็ยินดีเสมอ

    • ประเด็นสำคัญคือ ความต่างด้าน DAG immutability ระหว่าง git กับ jj
      jj ใช้ stable change ID ส่วน git ใช้ immutable commit ID
      เพราะแบบนี้ใน jj การ undo หรือ rebase จึงยืดหยุ่นกว่ามาก
    • jj จะซ่อนการเปลี่ยนแปลงที่ “ไม่น่าสนใจ” โดยอัตโนมัติ
      บางครั้งฉันก็อยากเห็นการเปลี่ยนแปลงมากกว่านี้ และสงสัยว่ามีตัวเลือกสำหรับแสดงทั้งหมดในครั้งเดียวไหม
  • jj ต่างจาก git มากพอที่จะคุ้มกับการลอง
    แค่ได้สัมผัสแนวทางอีกแบบก็ช่วยขยาย มุมมองด้านวิศวกรรม ได้แล้ว
    ไม่จำเป็นต้องลองทุกอย่างทั้งหมด แต่การเข้าใจ trade-off ของเวิร์กโฟลว์ที่ต่างกันเป็นเรื่องสำคัญ

    • แน่นอนว่าใน 99% ของกรณี การลองอะไรที่ ได้ประโยชน์น้อยมาก ก็อาจเป็นการเสียเวลา
  • ความสัมพันธ์ระหว่าง git กับ jj ให้ความรู้สึกเหมือนความสัมพันธ์ระหว่าง C กับ Python
    git คือการติดตามเชิงนิติวิทยาศาสตร์ ส่วน jj เหมือน บทต่าง ๆ ของเรื่องราว
    บางครั้งต้องกลับไปเขียนบทแรกใหม่เพื่อให้บทหลัง ๆ ลื่นไหลเป็นธรรมชาติมากขึ้น

    • สิ่งที่ jj ทำได้นั้น git ก็ทำได้เหมือนกัน แต่ วิธีคิดที่ฝังเป็นนิสัย จาก git กลับขัดขวาง
      jj ถูกออกแบบบนปรัชญาที่ว่า “working tree เองก็คือคอมมิต” และ “แม้แต่ conflict ก็สามารถคอมมิตได้”
  • ฉันรู้สึกว่าคำกล่าวอ้างว่า “ทรงพลังกว่าและง่ายกว่า” ต้องมี ตัวอย่างที่เป็นรูปธรรม

    • ถ้าจะยกข้อดีของ jj สักหน่อย ก็มี:
      • ไม่จำเป็นต้องแก้ rebase/merge conflict ทันที
      • จัดการคอมมิตได้ง่ายมาก โดยเฉพาะเมื่อใช้ jjui
      • jj มี operation log ที่ติดตามการเปลี่ยนแปลงสถานะของ git
      • การมีสาขาที่ไม่มีชื่อทำให้ทดลองอะไรได้อย่างอิสระ
      • เข้ากันได้กับ git อย่างสมบูรณ์ จึงใช้ปะปนกันในทีมได้
    • ตอนที่เราย้ายจาก SVN มา git เรารู้สึกว่าดีขึ้นมาก แต่ตอนนี้ก็ไม่ได้มีปัญหาใหญ่กับเวิร์กโฟลว์ของ git
    • คุณสามารถทำหลาย PR พร้อมกันในรีโพเดียวและ push แต่ละอันให้ตรงตามนั้นได้
      ถ้าไม่ได้มีความต้องการแบบนี้ คุณอาจไม่รู้สึกถึงคุณค่าของ jj
    • เสน่ห์ของ jj ไม่ได้อยู่ที่คำสั่ง แต่อยู่ที่ เวิร์กโฟลว์ที่เป็นธรรมชาติ
      ต้องลองใช้เองถึงจะเข้าใจ
    • แค่ jj undo อย่างเดียวก็คุ้มค่าแล้ว
      ใน git มักหลุดไปอยู่ในสถานะที่กู้ไม่ได้ง่าย ๆ แต่ใน jj แค่ undo ไม่กี่ครั้งก็แก้ได้
  • jj ทำให้ฉันมั่นใจในการใช้ DAG แบบไม่เชิงเส้น มากขึ้น
    สามารถจัดการการเปลี่ยนแปลงที่มีพ่อแม่หรือมีลูกหลายตัวได้อย่างอิสระ
    เมื่อก่อนฉันมักบังคับลำดับโดยไม่จำเป็น แต่ตอนนี้สามารถ แสดงความสัมพันธ์การพึ่งพาได้ชัดเจน
    กระบวนการรีวิวและส่งงานก็มีประสิทธิภาพขึ้นมาก

    • เลยสงสัยว่าบนการเปลี่ยนแปลงแบบแตกแขนงพวกนี้ มีใครใช้เวิร์กโฟลว์ mega-merge + absorb อยู่ไหม