מאבדים שליטה על הקוד עם PR ענקיים? gh stack יכול לסייע לכם

המודלים מייצרים PR-ים של 100 קבצים שאי אפשר לקרוא. GitHub Stacks נותנים שרשרת PR-ים קטנים שאפשר לנווט ביניהם, לעדכן ביחד ולמזג לפי שכבות בלי לאבד קונטקסט ובלי rebase ידני.

בפוסט זה אני יוצא מנקודת הנחה ש:

  1. אתם יודעים לעבוד עם גיט (הסבר ומדריך פה, יש אפילו ספר שכתבתי שמסביר על זה)
  2. אתם יודעים מה זה GH CLI
  3. אני יוצא מנקודת הנחה שיש לכם GH CLI מותקן ומחובר לאייג׳נט שלכם. אם לא – ממש ממש כדאי ואני מסביר פה למה כדאי לעבוד עם ה-CLI הזה יחד עם אייג׳נט.

אחת המחלות המשמעותיות שיש בעבודה עם LLM ואייג׳נטים של קוד כמו קורסור, קלוד קוד, קודקס ועוזריהם זה שמהר מאד מגיעים למצב שיש פול ריקווסטים עם המון קוד. המודלים הם פטפטנים ונוטים ליצור המון קוד. בעוד ב-PoC או מוצר דמה אין עם זה בעיה, יש כן בעיה כאשר עובדים על מוצר אמיתי ופתאום מגיעים למצב שמאד קל להכניס פיצ׳ר עם 100 קבצים שונים וזה מאד בעייתי להסתכל על זה.

אם אתם בדעה שבן אדם לא צריך להסתכל על הקוד? גם הפוסט הזה הוא בשבילכם. אם אתם משתמשים רק באייג׳נט לבדוק את הקוד, אז פול ריקווסטים קטנים עוזרים למזער טעויות. לפי דעתי כמובן זו התאבדות כי אני בדעה שכל שינוי שנכנס צריך אדם שיפקח עליו וישאל את השאלות. גם בגלל סכנה לדריפט (ראו את הפוסט שלי בנושא למי שלא מבין) וגם בגלל בעיות אחרות. חייבים לקרוא את הקוד לפני. אבל לקרוא 100 קבצים שונים זה לא ריאלי.

כך או כך, חייבים להכיר.

השיטה: פול ריקווסטים קטנים (אטומיים)

הדרך הכי טובה זה לפצל את הקוד ולדרוש בשלב התכנון (שהוא שלב קריטי לפני כתיבת הקוד) שיהיו פול ריקווסטים נפרדים וקצרים. א-ב-ל, הבעיה היא שזה עושה המון רעש ומנתק את הקונטקסט. קחו למשל פיצ׳ר פשוט: להוסיף למבדה שהיא אורקסטרטור. מה זה אומר? יחידת קוד שמפעילה יחידות קוד אחרות. גם אם זה ג׳יבריש בשבילכם, זה לא משנה. מדובר בפיצ׳ר שיש לו כמה צעדים:

  1. ליצור קוד שיוצר AWS Lambda (לא משנה אם ב-CDK או בדרך אחרת).
  2. ליצור בדיקות לקוד הזה.
  3. לכתוב את הלוגיקה של אורקסטרור שחי בלמבדה.
  4. ליצור בדיקות לקוד הזה.
  5. לכתוב בדיקת אינטגרציה לקוד כי מדובר פה באורקסטרטור.

אם אני יוצר פול ריקווסט לזה, יש המון קבצים ובן אדם יכול להעמיד פנים שהוא קורא הכל אבל בפועל זה לא יקרה.

בעיה: המון פול ריקווסטים מנותקים זה מזה

אני יכול להנחות את המודל ליצור המון פול ריקווסטים אבל אז אני מאבד את הקונטקסט. מי שמאשר את הפול ריקווסט יצטרך לעבור על המון כאלו בלי יכולת ממשית לעבור קדימה או אחורה. כלומר לעבור בנחת בין פול ריקווסט של צעד 1 לזה של 2,3 ו-4 ולראות את הכל בבת אחת. אם יש אנשים אחרים שעובדים על הריפוזיטורי יווצרו לי המון קונפליקטים בוודאות.

gh stacks

בדיוק בשביל זה גיטהאב יצרו את gh stacks. פיצ׳ר חדש אצלם. שימו לב, זה לא פיצ׳ר של גיט אלא של גיטהאב. מאד קל להשתמש בו והוא יוצר ״ערימה״ של פול ריקווסטים שקל מאד לנווט בינהם, לעדכן אותם אם פתאום יש קונפליקטים ובכלל לעבוד איתם. הפיצ׳ר קיים עכשיו ולא צריך לעשות שום דבר עבורו חוץ מלאשר אותו.

איך מפעילים? פשוט מבקשים מהאייג׳נט ליצור את הפול ריקווסט כ gh stacks.

ככה זה נראה למשל עם המשימה שתיארתי לעיל. אפשר להתרשם מבחינה גרפית שזה נראה דומה לפול ריקווסט רגיל אבל יש אייקון קטן (1/4) שלחיצה עליו מראה את כל הפול ריקווסטים הקשורים.

צילום מסך מ־GitHub: פול ריקווסט בשם "Adding optional Lambda timeout and the invoke SDK", מסומנת 1/4 בסטאק. נפתח תפריט Stack #43 ובו ארבעה PR-ים בשרשרת מעל main: #39 (השכבה הנוכחית, מודגשת), #40 handler שמפעיל workers במקביל, #41 רישום Lambda והרשאת invoke, ו־#42 תיעוד ו־echo round trip.

אם תכנסו אל רשימת הפול ריקווסטים, תוכלו לראות את כל ה stacked pr בדיוק כמו רגילים אבל עם אייקון קטן שמציג שהם חלק מסטאק.

רשימת בקשות משיכה פתוחות ב־GitHub: ארבעה PR-ים של barzik מאותו סטאק (#39–#42), כל אחד עם סימון מיקום בשרשרת (1/4 עד 4/4) וסטטוס משימות.

כשנכנסים לתוך אחד מהפול ריקווסטים האלו, הוא מתנהג כרגיל אבל אפשר לנווט בקלות לכל PR אחר שהוא חלק מהסטאק. אפשר לנתק פול ריקווסט מסטאק מסוים בקלות באמצעות לחיצה בלבד.

תפריט Stack #43 על PR בשכבה 4/4, עם כפתור Unstack pull requests. ארבע השכבות מוצגות בשרשרת מעל main.

אפשר לעשות מרג׳ לכולם ביחד או לכל אחד לחוד:

חלונית "Able to merge as a stack": מיזוג ה־PR ימזג גם שלושה PR-ים מתחתיו. כל ארבע השכבות מסומנות Ready. כפתור Merge stack מוגדר ל־4.

או רק לחלק (למשל השלושה הראשונים):

חלונית "Able to merge as a stack": מיזוג ה־PR הנוכחי ימזג גם PR אחד מתחתיו. שתי שכבות אמצעיות מסומנות, כפתור Merge stack מוגדר ל־2.

הוספת פול ריקווסט לסטאק

זה ממש ממש נוח. במיוחד כשדברים משתבשים. למשל, מה קורה אם אתה רוצה להוסיף פול ריקווסט כי רצית תוספת? אין בעיה, אפשר להוסיף. אני מנחה את האייג׳נט להוסיף ל-stacked PR, למשל משהו בסגנון הזה:

No, but there is a redundant integration, add another stacked PR: Remove integration test that invoke echo

אז אני אראה עוד פול ריקווסט והוא יצורף לסטאק:

באנר ירוק: "This pull request was added to stack #43". מתחתיו כותרת PR #44, "Dropping the redundant echo-only integration test", עם סטטוס Able to merge.

מישהו עדכן את הריפוזיטורי

אם הריפוזיטורי השתנה בגלל פול ריקווסט אחר שמורג׳ג׳, אין בעיה בכלל. אפשר לעדכן את הכל באמצעות rebase ש״משכתב את ההיסטוריה״.

באנר אזהרה: "This stack is out-of-date with its base branch", עם הסבר שצריך rebase על הגרסה האחרונה של main וכפתור Rebase stack.
דיאלוג Rebase stack: הסבר שכל ברנץ' יעבור rebase על זה שמתחתיו, יידחף ב־force-push, והתהליך ייעצר בקונפליקט הראשון. כפתורי Cancel ו־Rebase stack.

קונפליקט! הצילו!

אחד השיבושים שקורים בד״כ שמעשה שטן, יש לנו קונפליקט כי מישהו אחר ערמומי דחף קוד באיזור היקר שלנו לריפוזיטורי. פה למשל הstacks ממש מלהיבים כי ישר רואים שיש בעיה ואיפה. כאן למשל היה לי קונפלקיט. אפשר לראות מייד איפה ומה קרה:

הודעת שגיאה: rebasing נעצר בגלל קונפליקטים ב־PR #42. שכבות #39–#41 מסומנות Rebased, #42 עם Merge conflicts, #44 מסומן Skipped.

מה שעושים בשלב הזה זה פשוט להנחות את האייג׳נט שיתקן את הבעיה. ברגע שהוא מתקן, כל הפול ריקווסטים הבאים בתור גם מתעדכנים באופן קסום וכל הבילדים עוברים.

חלונית GitHub אחרי כשל ב־rebase של הסטאק: באנר "This branch has conflicts that must be resolved" עם הקובץ metrics/findings-log.md, ומתחתיו "Unable to merge as a stack". שכבות #39–#41 מסומנות Ready, #42 Not ready, ו־#44 Blocked downstack. כפתור Merge stack כבוי. אבל זו רק שאלה של זמן עד שהוא יעבוד.

אפשר לראות שזה ממש ממש נוח.

סיכום

אבל חייבים כמה מילות אזהרה. כמובן שצריך להזהר לא להיות עם יותר מדי פול ריקווסטים אטומיים וכמובן שאם תפצלו יותר מדי ויהיו לכם המון פול ריקווסטים ותהליך הבילד שלכם ארוך – זה יקח לכם יום שלם למרג׳ג׳ משהו. מצד שני… אם יש לכם תהליך בילד מאד ארוך יש לכם בעיה אחרת שצריך לפתור. כדאי וצריך להכיר את השיטה הזו. גם אם מקפידים לבחון כל פול ריקווסט עם עיניים אנושיות וגם אם נוקטים בגישה של אלבבאלה ושרק האייג׳נט יעבור על הפול ריקווסטים – פיצול שלהם יקל עליו ויעשה לו חיים קלים יותר וימזער בושות וטעויות.

פוסטים נוספים שכדאי לקרוא

פתרונות ומאמרים על פיתוח אינטרנט

העולם המדהים של Chrome debugging

איך תוכנות שונות מפעילות את כרום כרצונן? איך דיבאגר בפרונט עובד? צלילה לעומק לתוך העולם המופלא של CDP

יסודות בתכנות

הסבר קל ופשוט על Reinforcement Learning

הסבר פשוט למתכנתים שמסביר על איך למידה מחוזקת עובדת – הרבה יותר פשוט ממה שחשבתם ואפשר גם בג׳אווהסקריפט!

בינה מלאכותית

התקנה של Openclaw על רספברי פיי

איך מתקינים את הלהיט החדש בתחום על רספברי פיי? קל ופשוט ללא חומרה מיוחדת ועם הסבר מפורט.

גלילה לראש העמוד