הי צפריר,

אכן שאלה מעניינת.
קח בחשבון שהhash כולל בתהליך החישוב שלו גם את ה-timestamp של הקומיט, כך שגם
אם תמצא commit message שעונה על התנאי, לא תוכל לשחזר את התוצאה בריצה מאוחרת
יותר.
מכיוון שאתה לא משנה את ה tree אלא רק את הודעת הקומיט עצמו, יתכן שתוכל לחשב
את ה hash מבלי ליצור קומיט של ממש באמצעות git hash-object או פקודה דומה.
לפרטים נוספים על איך המימוש הפנימי של כל האובייקטים עובד, ממליץ על הפרק
הבא: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

On Tue, 19 Feb 2019 at 13:56, Tzafrir Cohen <tzaf...@cohens.org.il> wrote:

> שלום,
>
>
> השאלה שלי סוטה מהכיוון הכללי של הרשימה הזו בזמן האחרון ולמרבה הפליאה לא
> קשורה לאף ידיעה ב־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



-- 
יום טוב,
תומר בריסקר
_______________________________________________
Discussions mailing list
Discussions@hamakor.org.il
http://hamakor.org.il/cgi-bin/mailman/listinfo/discussions

לענות