שלום,

השאלה שלי סוטה מהכיוון הכללי של הרשימה הזו בזמן האחרון ולמרבה הפליאה לא
קשורה לאף ידיעה ב־ynet.


אני מנסה לעשות משהו קצת דבילי: יש לי מאגר גיט קטן ואני מנסה לדאוג
שה־hash של ה־commit האחרון יהיה מה שבחרתי. ליתר דיוק: הגרסה המקוצרת שלו:
מכיוון שזהו מאגר קטן, מדובר על המינימום: שבעה תווי hex. כלומר: ‎ 16^7או
‎2^28. זה כבר בתחום המעשי.


התחלתי מהסקריפט הבא:

#!/bin/bash

target="f00ba11"

max=$((16 ** 7))

commit_str() {
        git show -s --'pretty=tformat:%h' HEAD
}

commit_template="commit message title

Try ____

"

for i in `seq $max`; do

    if [ `commit_str` = "$target" ]; then

        break

    fi

    commit_msg=${commit_template/____/$i}

    git commit --amend -m "$commit_msg"

    echo -n "."

done


הבעיה הראשונה הייתה לולאת ה־for ו־seq. הפלט שלו ענקי וזה מפוצץ את תהליך
באש עצמו (המכונה שלי הייתה קצת חנוקה עם זכרון). הפכתי את זה ללולאת for
רגילה יותר (לא היה לי כוח לבדוק אם לבאש יש משהו משלו):

i=0
while [ $i -lt $max ]; do

    if [ `commit_str` = "$target" ]; then

        break

    fi

    commit_msg=${commit_template/____/$i}

    git commit --amend -m "$commit_msg"

    echo -n "."
    : $((i++))

done



בשלב הזה ראיתי מהו הקצב, והחלטתי שהוא לא מספיק טוב ושאני יכול להריץ כמה
במקביל. העתקתי את התיקיה לעוד שלושה עותקים. לכל אחד שמתי קובץ בשם
base_num, בהתחלה קראתי את תוכנו למשתנה, ועכשיו שורת יצירת התבנית הפכה להיות:

    commit_msg=${commit_template/____/$base_num:$i}

ואז שמתי לב שהאורך של ה־hash שמוצג לי כבר גדול מ־7. זה מוזר: נכון שאני
מייצר כל הזמן commit־ים לא מחוברים בכל הרצה של הלולאה, אבל מדי פעם רץ
git gc והוא אמור להיפטר מהם. ואז הבנתי שלא:

1. ה־reflog ממשיך להתייחס אליהם.

2. git gc מעיף אוטומטית רק commits בני שבועיים ויותר.


צריך להשתמש ב־git reflog expire: להגיד לו גם להתייחס לכל תוכן ה־log וגם
להפטר מכל מה שהוא מוצא, ולא רק מהישנים. את השינוי הבא לא להעתיק למקום
אחר אם אתם לא מבינים מה הוא עושה.

באותה הזדמנות הוספתי גם קובץ בשם start שמוסיף את הערך שממנו צריך להתחיל
בפעם הבאה שמריצים (אם אני מפסיק באמצע).

i=`cat start`
while [ $i -lt $max ]; do

    if [ `commit_str` = "$target" ]; then

        break

    fi

    commit_msg=${commit_template/____/$i}

    git commit --amend -m "$commit_msg"
    case "$i" in *0000)
        git reflog expire --all --expire=all
        git gc --prune=all
        echo $i >start
        ;;

    esac

    echo -n "."
    : $((i++))

done


לא מצאתי איך אפשר לעשות commit ללא עדכון ה־reflog. האם זה אפשרי?


וכן, אני מניח שזו לא הדרך היעילה ביותר לעשות את זה. הצעות לדרכים יעילות
יותר יתקבלו בברכה.


-- צפריר

_______________________________________________
Discussions mailing list
Discussions@hamakor.org.il
http://hamakor.org.il/cgi-bin/mailman/listinfo/discussions

לענות