stash، cherry-pick، tag
Stash, cherry-pick, and tags
گاهی وسط یک قابلیت هستی و هنوز وقت commit نیست، اما یک اصلاح فوری فوری میرسد. همین وقفه سه ابزار کوچک را معنیدار میکند: stash برای کنارگذاشتن موقت کار، cherry-pick برای آوردن یک تغییر مشخص و tag برای نامگذاری نسخه.
You are midway through a feature when an urgent release hotfix arrives. You do not need to commit unfinished work or copy the folder: we will set it aside, bring one known fix to the right branch, and name the tested release.
قابلیت نیمهکاره است؛ اصلاح فوری منتظر نمیماندThe feature is unfinished; the hotfix cannot wait
روی feature/search در دو فایل کار کردهای؛ یکی را هم ناحیه آمادهسازی کردهای. همتیمی میگوید باگ پرداخت در نسخهٔ انتشار باید همین حالا رفع شود. اگر شاخه عوض کنی چه میشود؟ اگر commit عجولانه بسازی، آیا واقعاً آمادهٔ تاریخچهٔ محصول است؟
You have edited two files on feature/search, staging one. A teammate reports that a payment bug in the release must be fixed now. What happens if you switch branches? If you make a hurried commit, is it ready for product history?
فصلهای ۳ و ۵ سه ناحیه و شاخه را جدا کردند؛ فصل ۶ نشان داد merge چهطور دو خط تاریخچه را نگه میدارد؛ فصل ۱۰ هم ردّ اشارهگرها را دنبال کرد. اینجا سه نیاز جدا داریم: کار نیمهتمام را موقت نگه داریم، تغییر انتخابی را روی شاخهٔ دیگر بسازیم و نسخهٔ آزمودهشده را نامگذاری کنیم.
Chapters 03 and 05 separated the three areas and branches; Chapter 06 showed how merge preserves history lines; Chapter 10 followed ref movements. Now we have three distinct needs: preserve unfinished work temporarily, apply one selected change on another branch, and name a tested release.
اول کار نیمهتمام را کنار بگذارFirst, set unfinished work aside
در مخزن تمرینی جدا، یک فایل ردیابیشده را تغییر بده و فایلی را ناحیه آمادهسازی کن. قبل از اجرا حدس بزن: بعد از stash پوشه و ناحیه آمادهسازی چه وضعی دارند؟
In a separate practice repository, edit a tracked file and stage another. Predict before running: what happens to the worktree and index?
git status --short git stash push -m "pause search for payment hotfix" git status --short git stash list
فرمان اول تغییرها را نشان میدهد. پس از stash push معمولاً پوشه و ناحیه آمادهسازی به وضعیت HEAD برمیگردند؛ stash list پیام رد تازه را نشان میدهد. این ثبت محلی است، نه commit روی شاخه و نه چیزی که همکار خودکار دریافت کند.
The first command shows the edits. After stash push, the worktree and index normally return to HEAD; stash list shows the new entry. This is local storage, not a branch commit or something a teammate automatically receives.
قبل از stash، status را بخوان. stash عادی تغییر فایلهای ردیابیشده را میگیرد؛ فایل ردیابینشده و ignored قواعد جدا دارند. ویرایشی که فقط در ادیتور است و هنوز ذخیره نشده، برای Git وجود ندارد.
Read status before stashing. A normal stash records tracked-file changes; untracked and ignored files have separate rules. An edit that exists only in an unsaved editor buffer does not exist for Git.
قبل از برگرداندن، داخل stash را ببینInspect before restoring
پس از چند وقفه، stash@{0} لزوماً کار همین قابلیت نیست. فهرست و patch را بخوان؛ اسم رد محتوایش را ثابت نمیکند.
After several interruptions, stash@{0} may not belong to this feature. Read the list and patch; the entry name does not prove its contents.
git stash list
git stash show --stat "stash@{0}"
git stash show -p "stash@{0}"list ترتیب و پیامها را نشان میدهد؛ show --stat فایلهای درگیر و -p خود diff را میدهد. خروجی را با کاری که یادت هست بسنج. دیدن patch ثابت نمیکند روی شاخهٔ تازه بیتعارض اعمال میشود.
list shows order and messages; show --stat summarizes paths, while -p displays the diff. Compare it with what you remember. Seeing the patch does not prove it will apply cleanly on a new branch.
refs/stash به تازهترین رد میرسد و reflog آن ردهای قدیمیتر را نامپذیر میکند. شمارهها با افزودن یا حذف تغییر میکنند و شناسهٔ پایدار نیستند.refs/stash reaches the newest entry; its reflog names older ones. Indices change as entries are added or removed and are not permanent IDs.ردیابینشده را جداگانه انتخاب کنInclude untracked files explicitly
فایل تازهای مثل draft-plan.md ساختهای، اما add نکردهای. stash معمولی آن را نمیگیرد؛ -u فایلهای ردیابینشده را هم میگیرد، اما ignoredها نه. -a ignored را هم شامل میکند و میتواند فایلهای تولیدی یا محلی را از پوشه بردارد؛ بیدلیل سراغش نرو.
You created draft-plan.md but did not add it. A normal stash excludes it; -u includes untracked files but not ignored ones. -a also includes ignored files and may remove generated or local data from the worktree; do not use it casually.
git status --short
git stash push -u -m "include new draft"
git stash show -p -u "stash@{0}"| نوع تغییرChange | stash push | stash push -u | stash push -a |
|---|---|---|---|
| tracked | ✓ | ✓ | ✓ |
| untracked | — | ✓ | ✓ |
| ignored | — | — | ✓ |
پس از اجرای فرمان، status و show -p -u را بخوان. یک فایل نبودنش دلیل نیست که حتماً در stash است؛ patch باید خود محتوای مورد انتظار را نشان دهد.
After running the command, inspect status and show -p -u. A missing file is not proof that it is in the stash; the patch must show the expected content.
apply نگه میدارد؛ pop بعد از موفقیت حذف میکندapply keeps it; successful pop removes it
هر دو تغییر را برمیگردانند؛ تفاوت در عمر رد است. apply آن را نگه میدارد تا بررسی کنی. pop فقط بعد از اعمال موفق حذفش میکند. اگر تعارض پیش بیاید، رد معمولاً میماند.
Both restore the changes; the difference is the entry's lifetime. Apply keeps it for inspection. Pop removes it only after successful application. If a conflict occurs, the entry normally remains.
| فرمانCommand | اعمالApply | حذف ردRemove entry | مناسب برایUse when |
|---|---|---|---|
stash apply | ✓ | خیرNo | میخواهی نتیجه را ببینی یا بعداً دوباره لازم داری.You want to inspect it or may need it again. |
stash pop | ✓ | پس از موفقیتAfter success | رد درست است و دیگر نباید در فهرست بماند.It is the right entry and should leave the list. |
stash drop | خیرNo | ✓ | پس از بررسی و اطمینان از بینیازی.After verifying it is no longer needed. |
در تعارض، وضعیت را بخوان، فایلها و ناحیه آمادهسازی را حل کن، ناحیه آمادهسازی و تست بگیر؛ بعد از اثبات نتیجه رد را drop کن. اگر میخواهی فایلهایی که قبل از stash ناحیه آمادهسازی بودند دوباره آمادهشده شوند، apply --index را امتحان کن؛ بازسازی ناحیه آمادهسازی هم ممکن است با تعارض روبهرو شود. stash مدیریت وقفه است، نه پشتیبان بلندمدت. برای کاری که باید بماند commit یا شاخه بساز.
On conflict, inspect status, resolve files and index, stage and test; drop only after proving the result. If you want paths that were staged before stashing to become staged again, try apply --index; restoring the index can also conflict. A stash manages an interruption, not long-term backup. Create a commit or branch for work that must persist.
stash کلیپبورد جادویی نیستA stash is not a magical clipboard
فصل ۲ نشان داد Git محتوا را در شیءهایی مثل blob، tree و commit نگه میدارد. stash هم با commitهای مخصوص وضعیت پوشه و ناحیه آمادهسازی را ثبت میکند و اشارهگر محلی refs/stash به تازهترین رد میرسد؛ reflog همان اشارهگر ردهای قبلی را قابلنامبردن میکند.
Chapter 02 showed Git storing content in objects such as blobs, trees, and commits. A stash is represented by special commits recording worktree and index states; the local ref refs/stash points to the newest entry, and its reflog makes earlier entries addressable.
این ساختار توضیح میدهد چرا میتوانی stash را diff کنی؛ اما نکتهٔ روزمره این است: محلی است، شاخه نیست، به مخزن راه دور نمیرود و بعد از حذف/پاکسازی ممکن است بازیابی نشود.
This structure explains why a stash can be diffed. The practical point is that it is local, not a branch, not sent to a remote, and may be unrecoverable after deletion and pruning.
اصلاح فوری آماده است؛ فقط همان تغییر را به نسخه انتشار بیاورThe hotfix is ready; bring only that change to release
همتیمی روی hotfix/payment-timeout تغییری ساخته و آزموده؛ شاخهٔ جستوجو هنوز نیمهکاره است. merge رابطهٔ دو شاخه را وصل میکند، اما امروز فقط یک commit مشخص باید روی release/2.4 هم باشد.
A teammate has made and tested a change on hotfix/payment-timeout, while search is unfinished. Merge connects branch histories, but today one known commit must also appear on release/2.4.
اگر commit هنوز در clone نیست، fetch کن؛ رهگیریِ مخزن راه دور شاخه فقط آخرین وضعیت fetchشده است. اینجا شناسه شیء محلی داریم. قبل از اجرا، مقصد و patch را ثابت کن:
If the commit is not in your clone, fetch; a remote-tracking branch is only the last fetched state. Here the OID is local. Prove the target and patch first:
git status --short --branch git show --stat --oneline HOTFIX_OID git switch release/2.4 git status --short --branch git cherry-pick HOTFIX_OID git show --stat --oneline HEAD
HOTFIX_OID را با شناسهٔ واقعی عوض کن. show میگوید چه patchی را انتخاب کردهای؛ cherry-pick آن را روی والد جاری بازمیسازد. معمولاً commit تازه شناسه شیء تازه دارد چون والد یا فراداده فرق میکند؛ commit اصلی سر شاخهٔ اصلاح فوری میماند.
Replace HOTFIX_OID with the real ID. show identifies the selected patch; cherry-pick reconstructs it on the current parent. The new commit normally has a new OID because its parent or metadata differs; the source remains on hotfix.
merge رابطه را میآورد؛ cherry-pick تغییر راmerge brings the relationship; cherry-pick brings the change
اگر کل خط کار و رابطهٔ والدها آن باید وارد نسخه انتشار شود، merge را بررسی کن. اگر فقط patch مشخصی لازم است و شاخهٔ مبدا نباید یکجا ادغام شود، cherry-pick محدودتر است. انتخاب را بر اساس تاریخی بکن که تیم بعداً باید بخواند.
If the whole line of work and its ancestry should enter release, consider merge. If only one patch is needed and the source branch should not be integrated wholesale, cherry-pick is narrower. Choose based on the history your team needs to read.
| نیازNeed | merge | cherry-pick |
|---|---|---|
| چه چیزی میآید؟What comes over? | رابطهٔ شاخه و commitهای قابلدسترسیBranch relationship and reachable commits | اثر commit انتخابیEffect of selected commit |
| والد commitCommit parent | تاریخچه حفظ؛ fast-forward یا merge commitHistory preserved; fast-forward or merge commit | commit تازه فرزند مقصدNew commit descends from target |
| پرسشQuestion | آیا این خط کار باید ادغام شود؟Should this line of work be integrated? | کدام patch دقیقاً لازم است؟Which exact patch is needed? |
تعارض آمد؟ اول وضعیت را بخوانConflict? Read the state first
اگر cherry-pick با تعارض متوقف شد، کورکورانه تکرارش نکن. وضعیت فایلهای حلنشده را نشان میدهد؛ بعد انتخاب کن تغییر را نگه داری یا عملیات را لغو کنی.
If cherry-pick stops with a conflict, do not repeat it blindly. Status identifies unresolved files; then decide whether to keep the change or cancel.
git status # resolve intentionally git add path/to/resolved-file git cherry-pick --continue # alternatively, cancel the operation git cherry-pick --abort
بعد از حل و ناحیه آمادهسازی، --continue commit را میسازد؛ --abort به قبل از عملیات جاری برمیگردد. با درخت تمیز شروع کن تا تغییرهای نامرتبط درگیر نشوند. اگر patch خالی یا تکراری شد، log و diff را بسنج؛ شاید تغییر پیشتر آمده یا مقصد اشتباه است. commit خالی را فقط برای خاموشکردن خطا نساز.
After resolving and staging, --continue creates the commit; --abort returns to the pre-operation state. Start with a clean worktree so unrelated edits are not involved. If the patch is empty or redundant, inspect log and diff; it may already exist or the target may be wrong. Do not create an empty commit just to silence an error.
اول بپرس push شده؟ همتیمی بر آن بنا کرده؟ وضعیت فایلها چیست؟ فصل ۹ بین کار محلی و تاریخچهٔ مشترک فرق گذاشت؛ اشارهگر امن بساز و مرز را رعایت کن.
First ask whether it was pushed, whether a teammate built on it, and what the worktree contains. Chapter 09 distinguished local work from shared history; create a safety ref and respect that boundary.
نسخهٔ آزمودهشده را با tag نامگذاری کنName the tested release with a tag
شاخه خط کاریای است که حرکت میکند؛ tag نامی است که روی نقطهای از تاریخچه میگذاری تا نسخه یا رویدادی را مشخص کنی. فصل ۲ ساختارش را معرفی کرد: tag سبک اشارهگر مستقیم به شیء است؛ tag نشانهدار شیء جدا با پیام، زمان و tagger میسازد. برای نسخه انتشار معمولاً tag نشانهدار مناسبتر است.
A branch is a moving line of work; a tag names a point in history as a release or event. Chapter 02 introduced the structure: a lightweight tag is a ref directly to an object; an annotated tag creates a separate object with message, date, and tagger. Annotated tags are usually more useful for releases.
| نوعKind | ساختارStructure | کاربردUse |
|---|---|---|
| سبکLightweight | اشارهگر مستقیم به شیء هدفRef directly to target object | موقت یا محلیTemporary or local marker |
| نشانهدارAnnotated | tag شیء با پیام/زمان/tagger؛ امضا اختیاریTag object with message/date/tagger; optional signature | نسخهٔ انتشارRelease version |
قبل از انتشار، مقصد tag را ثابت کنVerify the tag target before publishing
tag روی commit اشتباه نسخهٔ درست نمیسازد. شاخه، تست و commit جاری را بررسی کن؛ سپس tag بساز و با show مقصدش را بخوان.
A tag on the wrong commit does not make a correct release. Verify branch, tests, and current commit; create the tag, then inspect its target with show.
git status --short --branch git log -1 --oneline git tag -a v2.4.1 -m "Release 2.4.1: payment timeout fix" git show --no-patch --decorate v2.4.1 git push origin release/2.4 git push origin v2.4.1 git ls-remote --tags origin
show پیام و مقصد commit را نشان میدهد. اگر نام از قبل هست، توقف کن و مقصد محلی و مخزن راه دور را بررسی کن؛ tag منتشرشده ممکن است مبنای ساخت دیگران باشد. push شاخه تضمین نمیکند tag هم رفته؛ tag مشخص را جدا push کن. push --tags همهٔ tagهای محلی، حتی آزمایشی/خصوصی را میفرستد؛ فرمان پیشفرض انتشارش نکن.
show displays message and target. If the name exists, stop and inspect local and remote targets; a published tag may anchor other builds. Pushing a branch does not guarantee its tag was sent; push the exact tag separately. push --tags sends all local tags, including experimental or private ones; do not make it the default.
Git اجازهٔ جابهجایی tag محلی یا حذف مخزن راه دور را میدهد، اما نسخهگذاری قرارداد تیمی است. برای tag منتشرشدهٔ اشتباه با مصرفکنندگان هماهنگ کن؛ نام تازه معمولاً از عوضکردن معنای نام عمومی کمخطرتر است. امضای کوتاه: tag -s با کلید تنظیمشده امضا میکند و tag -v آن را میسنجد؛ اعتماد به هویت امضاکننده هم لازم است.
Git permits moving a local tag or deleting one remotely, but release naming is a team contract. Coordinate if a published tag is wrong; a new name is often safer than changing a public name's meaning. Briefly: tag -s signs with a configured key, and tag -v verifies it; trust in the signer's identity still matters.
پروژهٔ کوچک: وقفه، اصلاح فوری، انتشارMini-project: interruption, hotfix, release
سه کار جدا، یک جریان پیوسته
Three distinct jobs, one continuous story
این پروژه یک وقفهٔ واقعی را شبیهسازی میکند: وسط یک قابلیت هستی، یک اصلاح فوری میرسد و بعد باید نسخه را منتشر کنی. کار نیمهتمام نباید قاطی اصلاح فوری شود و نباید هم گم شود. هر مرحله را با وضعیت و log ثابت میکنیم تا معلوم باشد دقیقاً چه چیزی کجا رفته است.
In a fresh repository, leave a feature unfinished, bring the hotfix to release, and tag it after testing. Prove the feature can continue and the tag points to the inspected version.
ساخت سناریو
Set up the scenario
فقط در پوشهٔ تازهٔ interrupt-release-lab اجرا کن؛ مخزن واقعی را جایگزین نکن.
Run only in a new interrupt-release-lab folder; do not substitute a real repository.
mkdir interrupt-release-lab && cd interrupt-release-lab git init -q git config user.name "Git Learner" git config user.email learner@example.test printf 'timeout=30\nsearch=off\n' > app.conf git add app.conf && git commit -m "Create release baseline" git branch -M main git switch -c release/2.4 git switch -c hotfix/payment-timeout printf 'timeout=10\nsearch=off\n' > app.conf git commit -am "Reduce payment timeout" git switch release/2.4 git switch -c feature/search printf 'timeout=30\nsearch=partial\n' > app.conf git add app.conf printf 'unfinished parser\n' > search-draft.txt
اکنون status --short باید تغییر آمادهشده و فایل ردیابینشده نشان دهد. ایستگاهها را یکییکی انجام بده و قبل از drop همیشه محتوا را ثابت کن:
Now status --short should show a staged change and an untracked file. Complete the checkpoints one at a time, verifying content before any drop:
- وقفه را ثبت کنRecord the interruption
هر دو فایل را با پیام روشن و گزینهٔ مناسب stash کن. با وضعیت و فهرست stash ثابت کن پوشه تمیز و رد موجود است.
Stash both files with a clear message and the right option. Use status/list to prove the worktree is clean and the entry exists.
- اصلاح را انتخاب کنSelect the fix
روی نسخه انتشار برو، شناسه شیء اصلاح فوری را با log/show بشناس و cherry-pick کن. مقصد، diff و والد commit تازه را بررسی کن.
Switch to release, identify the hotfix OID with log/show, and cherry-pick. Inspect the target, diff, and new parent.
- آزمون و tagTest and tag
فایل را بخوان، tag نشانهدار
v2.4.1-labبساز و با show مقصدش را ثابت کن. اگر bare مخزن راه دور اختیاری ساختی، tag را جدا push و با ls-remote بررسی کن.Inspect the file, create annotated tag
v2.4.1-lab, and verify its target with show. If you make an optional bare remote, push the tag separately and inspect with ls-remote. - کار قابلیت را برگردانRestore the feature work
به قابلیت برگرد و stash را با apply اعمال کن. status/diff ثابت کند فایل آمادهشده و ردیابینشده برگشتهاند. بعد از این مدرک، رد را drop کن یا نگه دار.
Return to feature and apply the stash. Prove with status/diff that staged and untracked files returned. Afterward, drop or keep the entry.
اگر ترتیب یادت رفتIf you lose the sequence
اول پوشه را امن کن؛ بعد patch را روی مقصد درست بساز؛ tag فقط بعد از آزمون. فایل تازه به -u نیاز دارد؛ apply رد را نگه میدارد.
First make the worktree safe; then apply the patch on the right target; tag only after testing. The new file needs -u; apply keeps the entry.
اگر cherry-pick تعارض دادIf cherry-pick conflicts
وضعیت را بخوان، نتیجه را آگاهانه بنویس، ناحیه آمادهسازی و continue کن. اگر مقصد غلط است، abort؛ تا علت را نفهمیدهای ادامه نده.
Read status, write the intended result, stage, and continue. If the target is wrong, abort; do not continue before understanding the cause.
- وضعیت هر دو شاخه با
git status --short --branch - Both branches with
git status --short --branch - گراف با
git log --oneline --graph --decorate --all - Graph with
git log --oneline --graph --decorate --all - مقصد tag با
git show --no-patch --decorate v2.4.1-lab - Tag target with
git show --no-patch --decorate v2.4.1-lab - diff قابلیت بعد از apply و توضیح اینکه چرا شناسه شیء اصلاح فوری و نسخه انتشار یکی نیستند.
- Feature diff after apply and an explanation of why hotfix and release OIDs differ.
تمرینها: انتخاب درست، نه حفظ فرمانExercises: choose well, do not memorise
برای هر سؤال فقط بپرس «چه چیزی را میخواهم جابهجا کنم؟» کار ثبتنشده، تغییر داخل یک commit و نام یک نسخه سه جنس متفاوتاند. stash، cherry-pick و tag هم به همین دلیل سه ابزار جدا هستند؛ اگر مسئله را درست نام ببری، انتخاب ابزار ساده میشود.
Start with the model, then move to team incidents. Rely on what was actually recorded, not branch names or wishful thinking.
دو فایل ردیابیشده تغییر کردهاند، یکی آمادهشده است. آیا stash معمولی هر دو را ثبت میکند و بعد از موفقیت چه میشود؟
Two tracked files changed, one staged. Does a normal stash record both, and what happens after success?
توضیح / Explanation
بله؛ تغییرهای آمادهشده و آمادهنشده ثبت میشوند و ناحیهها معمولاً به HEAD برمیگردند. stash commit روی شاخه نیست.
Yes; staged and unstaged edits are recorded and the areas normally return to HEAD. A stash is not a branch commit.
new.md ردیابینشده بود و بعد از stash ناپدید شد. چه میکنی؟
new.md was untracked and disappeared after stashing. What do you do?
غیبت مدرک نیست / Absence is not proof
بررسی کن رد با -u ساخته شده یا نه: stash list و stash show -p -u. اگر محتوا آنجا نیست، نسخهٔ ویرایشگر یا سیستم فایل را بجوی؛ بازیابی تضمینشده نیست.
Check whether the entry used -u with stash list/show. If the content is absent, check editor/filesystem recovery; restoration is not guaranteed.
stash را فقط میخواهی بخوانی، نه اعمال کنی. چه میزنی؟
You want to inspect, not apply, a stash. What do you run?
بازرسی / Inspection
git stash list و git stash show -p "stash@{n}". اینها پوشه را تغییر نمیدهند.
Use git stash list and git stash show -p "stash@{n}". They do not modify the worktree.
apply تغییرها را برگردانده ولی رد هنوز هست. شکست است؟
apply restored the edits, but the entry remains. Is that failure?
رفتار مورد انتظار / Expected behavior
خیر؛ apply نگه میدارد. بررسی کن و اگر دیگر لازم نیست drop کن. pop بعد از موفقیت حذف میکند.
No; apply keeps it. Verify, then drop if no longer needed. Pop removes it after success.
ردیابینشده باید ذخیره شود، ignored نه. کدام گزینه؟
Include untracked, but exclude ignored files. Which option?
دامنهٔ محدود / Narrow scope
-u. گزینهٔ -a ignoredها را هم میگیرد و بیش از نیاز است.
Use -u. -a also includes ignored files and is broader than needed.
stash pop تعارض داد. آیا رد حذف شد؟
Stash pop conflicted. Was the entry removed?
اول بررسی / Inspect first
معمولاً نه. وضعیت و list را بخوان، تعارض را حل و ناحیه آمادهسازی کن، تست بگیر؛ بعد از اثبات نتیجه drop کن.
Usually not. Inspect status/list, resolve and stage, test, and drop only after verifying.
سه ابزار این فصل را قاطی نکن. از اینجا به بعد هر تمرین را با یک اسم شروع کن: «کار نیمهتمام»، «تغییر داخل commit»، یا «نام یک نسخه». همین اسم معمولاً ابزار را مشخص میکند.
Do not mix the three tools in this chapter. From here, label each problem first: “unfinished work,” “a change inside a commit,” or “a release name.” That label usually identifies the right tool.
یک patch باید به نسخه انتشار بیاید ولی کل شاخه نه. چه روشی؟
One patch must reach release, but not the whole branch. Which operation?
انتقال انتخابی / Selective integration
cherry-pick؛ اول شناسه شیء، diff و شاخهٔ مقصد را ثابت کن. برای انتقال مسیر تاریخ کامل merge را بررسی کن.
Cherry-pick; first verify OID, diff, and target branch. Use merge when the full lineage is needed.
چرا commit cherry-pickشده معمولاً شناسه شیء دیگری دارد؟
Why does a cherry-picked commit usually have another OID?
والد بخشی از هویت است / Parent is part of identity
commit تازه روی والد مقصد ساخته میشود و فراداده هم ممکن است فرق کند. patch مشابه است؛ شیء الزاماً یکی نیست.
The new commit is built on the target parent and metadata may differ. The patch can be similar while the object differs.
دو commit وابسته باید با رابطهٔ والدها وارد شاخه شوند. merge یا cherry-pick؟
Two dependent commits should enter with ancestry. Merge or cherry-pick?
تاریخچه را حفظ کن / Preserve history
معمولاً merge؛ cherry-pickها patchها را بازسازی میکنند و مسیر تاریخ مبدا را همانطور حفظ نمیکنند.
Usually merge; cherry-picks reconstruct patches rather than preserving the source lineage in the same way.
بعد از حل و ناحیه آمادهسازی تعارض، چهطور cherry-pick را تمام میکنی؟
After resolving and staging, how do you finish the cherry-pick?
Continue یا abort
--continue commit را ثبت میکند؛ اگر انتخاب غلط بود --abort. --skip برای رد commit جاری در یک توالی چندتایی است.
--continue records the commit; use --abort if the choice was wrong. --skip skips the current commit in a sequence.
تلاش دوم patch خالی شد. آیا --allow-empty راه پیشفرض است؟
A second attempt produces an empty patch. Is --allow-empty the default fix?
علت را پیدا کن / Find the cause
نه؛ تغییر شاید از قبل آمده، مقصد غلط است یا commit ذاتاً خالی است. log و diff را بسنج و skip/abort را آگاهانه انتخاب کن.
No; it may already be applied, the target may be wrong, or the source may be intentionally empty. Inspect log/diff and choose skip or abort deliberately.
برای برچسب محلی موقت و نسخه انتشار دارای پیام، چه tagهایی میسازی؟
Which tags suit a temporary local marker and a release with a message?
نوع از قصد میآید / Intent chooses kind
سبک برای نشانهٔ موقت؛ نشانهدار برای نسخه انتشار، مثلاً git tag -a v2.4.1 -m "Release" HEAD. مقصد را با show بخوان.
Lightweight for a temporary marker; annotated for a release, e.g. git tag -a v2.4.1 -m "Release" HEAD. Inspect it with show.
تمرینهای آخر چند ابزار را پشت سر هم میآورند. مهم این است که مرز هر مرحله روشن بماند: stash نباید اصلاح فوری را ببلعد، cherry-pick نباید تاریخ شاخهٔ مبدا را منتقل کند و tag باید دقیقاً روی commit آزمودهشده بنشیند.
The final exercises chain the tools together. Keep each boundary clear: the stash must not swallow the hotfix, cherry-pick must not import the source branch ancestry, and the tag must point at the tested commit.
شاخه push شد ولی tag در مخزن راه دور نیست. چه میکنی؟
The branch was pushed, but the tag is absent remotely. What do you do?
ref جدا، push جدا / Separate ref, separate push
git push origin v2.4.1، سپس git ls-remote --tags origin. شاخه push بهتنهایی انتشار tag را ثابت نمیکند.
Run git push origin v2.4.1, then git ls-remote --tags origin. A branch push alone does not prove tag publication.
نام tag از قبل هست و مدیر میخواهد دوباره بسازی. قدم اول؟
The tag name already exists and a manager asks you to recreate it. First step?
نام را جابهجا نکن / Do not move it casually
git show TAG و git ls-remote --tags origin را بررسی کن. اگر مقصد فرق دارد، هماهنگ شو؛ ممکن است نام عمومی مبنای ساخت باشد.
Inspect git show TAG and the remote tags. If the target differs, coordinate; public names may anchor builds.
سه tag محلی داری، فقط یکی باید منتشر شود. چرا push --tags پرریسک است؟
You have three local tags, but only one should be published. Why is push --tags risky?
دامنهٔ ناخواسته / Unintended scope
همهٔ tagهای محلی را میفرستد، حتی آزمایشی یا خصوصی. نام دقیق را push و مخزن راه دور را بررسی کن.
It sends all local tags, including experimental or private ones. Push the exact name and inspect the remote.
وسط cherry-pick میفهمی دو commit وابستهٔ دیگر لازماند. چه میکنی؟
Mid-cherry-pick, you learn two dependent commits are also required. What now?
توقف و طراحی دوباره / Pause and reconsider
وضعیت را بخوان؛ اگر توالی جاری است abort کن، بعد تصمیم بگیر merge مسیر تاریخ بهتری میدهد یا چند cherry-pick با ترتیب مشخص لازماند. بیبررسی ادامه نده.
Inspect status; if the sequence is active, abort, then decide whether merge preserves better lineage or ordered cherry-picks are needed. Do not continue blindly.
pop موفق شد ولی تست fail شد و رد هم ناپدید شد. اول چه میخوانی؟
Pop succeeded but tests failed and the entry disappeared. What do you inspect first?
فرمان موفق، کار نه / Command success is not task success
وضعیت، diff، ردیابینشدهها و تست را. شاید بخشی هرگز stash نشده یا زمینه patch را عوض کرده. بازیابی را تضمین نکن؛ دفعهٔ بعد apply، وارسی و بعد drop.
Inspect status, diff, untracked paths, and tests. Some work may never have been stashed or context changed the patch. Do not promise recovery; next time apply, verify, then drop.
ساخت با توضیح نسخه انتشار مدیر برای v3.0.0 نمیخواند؛ شاخه push شده و tag شاید جا مانده. سه شاهد؟
The build differs from the release manager's description of v3.0.0; the branch was pushed and the tag may be missing. What three facts do you prove?
سه مقصد را جدا کن / Separate three targets
log --decorate برای commit شاخه، show v3.0.0 برای tag محلی، و ls-remote --tags origin برای مخزن راه دور. اگر مقصد مخزن راه دور غلط است، قبل از تغییر هماهنگ شو.
Use log --decorate for the branch commit, show v3.0.0 for the local tag, and ls-remote --tags origin for the remote. Coordinate before changing an incorrect public target.
وقتی میدانی چه میخواهی، این ابزارها کمک میکنندThese tools help when you know what you need
این سه ابزار وقتی به درد میخورند که دقیقاً میدانی چه چیزی میخواهی. فصل بعد برعکس است: فقط میدانیم جایی در چند ده commit گذشته یک باگ وارد شده و باید با کمترین آزمون، مرزش را پیدا کنیم.
You can preserve unfinished work, apply a known patch, and name a tested version. But if a bug appeared weeks ago and you do not know which commit introduced it, neither stash nor cherry-pick answers that question. Chapter 12 turns it into a systematic search with git bisect.
مرور کوتاهQuick reference
stash push -mبرای ردیابیشده؛-uردیابینشده را میگیرد، نه ignored را.stash push -mfor tracked edits;-uincludes untracked, not ignored, files.list/show -pرا قبل از restore بخوان؛ apply نگه میدارد، pop بعد از موفقیت حذف میکند.- Inspect with list/show; apply keeps the entry, successful pop removes it.
- stash محلی و موقت است؛ drop فقط بعد از بررسی.
- A stash is local and temporary; drop only after inspection.
- قبل از cherry-pick مقصد و patch را ثابت کن؛ تعارض را continue یا abort کن.
- Verify target and patch before cherry-picking; continue or abort a conflict deliberately.
- نسخه انتشار را معمولاً با tag نشانهدار نامگذاری و با show بررسی کن.
- Usually use an annotated tag for a release and verify with show.
- tag مشخص را push کن؛
--tagsهمه را میفرستد. - Push one named tag;
--tagssends them all.
stash برای توقف کوتاه، cherry-pick برای آوردن یک تغییر مشخص و tag برای نامگذاری یک نقطهٔ تاریخ است. اگر یکی از این سه را برای مسئلهٔ دیگری استفاده میکنی، یک بار دیگر سؤال اصلی را بخوان.
For behavior in your Git version, see the official manuals for git stash, git cherry-pick, git tag, and git push. Configuration may affect pushes; inspect the remote result.