နားလည်ထားရမယ့် အချက်
`git reset` နဲ့ `git revert` နှစ်ခုစလုံးက ပြောင်းလဲမှုတွေကို ပြန်ဖျက်ပေမယ့် history ကို ကိုင်တွယ်ပုံ ဆန့်ကျင်ဖက်ပါ။ Reset က branch pointer ကို နောက်ပြန်ရွှေ့ပြီး history ကို တိုစေပြီး၊ Revert ကတော့ ရှိပြီးသား commit ကို မထိဘဲ ဆန့်ကျင်ဖက် commit အသစ်တစ်ခု ဖန်တီးပေးပါတယ်။
| Tool | History ဘာဖြစ်လဲ |
|---|---|
| reset | Branch pointer ကို နောက်ပြန်ရွှေ့သည်၊ နောက်ပိုင်း commit များ ချွတ်ထွက်ပြီး history တိုသွားသည် |
| revert | Commit တစ်ခုကို ပြန်ဖျက်ပေးသည့် commit အသစ် ထည့်သည်၊ ရှိပြီးသား ဘာမှ ပြန်မရေးဘဲ history ရှည်လာသည် |
Commit ဆိုးက private, push မလုပ်ရသေးရင် reset ပြဿနာ မရှိပါဘူး။ Push ပြီး teammate pull ယူသွားရင်တော့ reset+force-push က သူတို့ history ကို ပြန်ရေးပစ်တာနဲ့ တူလို့ revert ကသာ safe ပါတယ်။
- `--soft` — ပြောင်းလဲမှုတွေကို staged ထားပြီး ပြန် commit လုပ်ဖို့ အသင့်ဖြစ်စေသည်
- `--mixed` (default) — unstage လုပ်သော်လည်း working directory ထဲ ကျန်ရစ်သည်
- `--hard` — အားလုံးကို လုံးဝ ဖျက်ပစ်သည်၊ undo button မရှိပါ
- Reset
- လက်ရှိ branch pointer ကို commit တခြားတစ်ခုဆီ ရွှေ့ပေးပါတယ်၊ ရွေးချယ်ရင် staging area နဲ့ working directory ကိုပါ ပြောင်းပေးပါတယ် — local history ကို ပြန်ရေးပါတယ်။
- Revert
- ရှိပြီးသား commit တစ်ခုရဲ့ ပြောင်းလဲမှုကို ပြန်ဖျက်ပေးတဲ့ commit အသစ်တစ်ခု ဖန်တီးပေးပါတယ်၊ ရှိပြီးသား commit ဘယ်ဟာမှ မပြောင်းလဲစေပါဘူး — shared history အတွက် safe ပါတယ်။
RESET (SHORTENS HISTORY) VS REVERT (ADDS COMMIT)
------------------------------------------------
RESET (SHORTENS HISTORY) VS REVERT (ADDS COMMIT)
----------------------------------------------------
Before: C1 --- C2 --- C3 <- main
git reset --hard C1:
C1 <- main (C2, C3 detached, shorter)
git revert C3:
C1 --- C2 --- C3 --- C4 <- main
(C4 undoes C3, longer)လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Share ပြီးသား commit ဆိုးအတွက် `git revert <hash>` (with `--no-edit`) က ပြောင်းလဲမှုကို ပြန်ဖျက်ပေးတဲ့ commit အသစ်တစ်ခု ဖန်တီးပေးပါတယ်။
`git log --oneline` ကို revert မလုပ်ခင်နဲ့ လုပ်ပြီးနောက် နှိုင်းယှဉ်ရင် original commit ဆက်ရှိနေဆဲ၊ အပေါ်က revert commit အသစ်က effect ကို ပြန်ဖျက်ပေးနေတာ တွေ့ရပါလိမ့်မယ်။
| Mode | ပြောင်းလဲမှု ဘယ်ရောက်လဲ |
|---|---|
| --soft | Staged, ပြန် commit လုပ်ဖို့ အသင့် ('Changes to be committed') |
| HEAD (mixed) | Unstaged ဖြစ်သွားပေမယ့် file ထဲမှာ ရှိနေဆဲ ('Changes not staged for commit') |
git reset --hard က uncommitted work ကို ဖျက်ဆီးပါတယ်
`--hard` က staged, unstaged ပြောင်းလဲမှုနှစ်ခုစလုံးကို အမြဲတမ်း ဖျက်ပစ်ပါတယ် — ရိုးရှင်းစွာ ပြန်ယူလို့ မရပါဘူး။ `--hard` reset မလုပ်ခင် `git status` ကို အမြဲ run ပြီး ဘာတွေ ဆုံးရှုံးတော့မလဲ ကြည့်ပါ။
အတူတူ စမ်းရေးကြည့်မယ်
git init -q -b main
git config user.name "Thuta Learner"
git config user.email "learner@example.com"
# --- Part 1: revert (safe on shared history) ---
mkdir part1 && cd part1
git init -q -b main
git config user.name "Thuta Learner"
git config user.email "learner@example.com"
export GIT_AUTHOR_NAME="Thuta Learner"
export GIT_AUTHOR_EMAIL="learner@example.com"
export GIT_COMMITTER_NAME="Thuta Learner"
export GIT_COMMITTER_EMAIL="learner@example.com"
echo "body { color: black; }" > style.css
git add style.css
GIT_AUTHOR_DATE="2026-01-04T09:00:00" GIT_COMMITTER_DATE="2026-01-04T09:00:00" git commit -m "Add base styles"
echo "body { color: red; }" >> style.css
git add style.css
GIT_AUTHOR_DATE="2026-01-04T10:00:00" GIT_COMMITTER_DATE="2026-01-04T10:00:00" git commit -m "Change text to red (bad idea)"
BAD_COMMIT=$(git rev-parse HEAD)
git log --oneline
GIT_AUTHOR_DATE="2026-01-04T11:00:00" GIT_COMMITTER_DATE="2026-01-04T11:00:00" git revert --no-edit $BAD_COMMIT
git log --oneline
cat style.css
cd ..
# --- Part 2: reset --soft / mixed (separate fresh repo) ---
mkdir part2 && cd part2
git init -q -b main
git config user.name "Thuta Learner"
git config user.email "learner@example.com"
echo "console.log('start');" > app.js
git add app.js
GIT_AUTHOR_DATE="2026-01-05T09:00:00" GIT_COMMITTER_DATE="2026-01-05T09:00:00" git commit -m "Initial commit"
echo "console.log('oops typo comit');" >> app.js
git add app.js
GIT_AUTHOR_DATE="2026-01-05T10:00:00" GIT_COMMITTER_DATE="2026-01-05T10:00:00" git commit -m "Bad commit with typo"
git log --oneline
git reset --soft HEAD~1
git status
git reset HEAD
git status$ git log --oneline
23ae617 Change text to red (bad idea)
a43964a Add base styles
$ git revert --no-edit 23ae617
[main b1d22c5] Revert "Change text to red (bad idea)"
Date: Sun Jan 4 11:00:00 2026 +0900
1 file changed, 1 deletion(-)
$ git log --oneline
b1d22c5 Revert "Change text to red (bad idea)"
23ae617 Change text to red (bad idea)
a43964a Add base styles
$ cat style.css
body { color: black; }
--- Part 2: reset ---
$ git log --oneline
e379b53 Bad commit with typo
1e07e9f Initial commit
$ git reset --soft HEAD~1
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: app.js
$ git reset HEAD
Unstaged changes after reset:
M app.js
$ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: app.js
no changes added to commit (use "git add" and/or "git commit -a")၅ မိနစ် စမ်းကြည့်
Scratch repo မှာ commit နှစ်ခု လုပ်ပါ။ ဒုတိယ commit ကို `git revert` နဲ့ ပြန်ဖျက်ပြီး `git log --oneline` နဲ့ history က တိုသွားခြင်းမဟုတ်ဘဲ တိုးလာခြင်းဖြစ်ကြောင်း အတည်ပြုပါ။ ပြီးရင် သီးခြား scratch repo မှာ ပြန်ချေဖျက်ရမယ့် commit တစ်ခု လုပ်ပြီး၊ reset mode သုံးမျိုးလုံးကို အစဉ်လိုက် စမ်းကြည့်ပါ (`--soft`, ပြီးရင် plain `git reset HEAD` နဲ့ unstage လုပ်ခြင်း) — တစ်ခုစီပြီးတိုင်း `git status` run ပြီး ဘာအတိအကျ ပြောင်းသွားလဲ မှတ်သားပါ။
သတိလေးတစ်ချက်
Push လုပ်ပြီး တစ်ယောက်ယောက် pull ယူသွားပြီးသား commit တွေအပေါ် `git reset --hard` (သို့ reset ပြီးနောက် force-push) သုံးလိုက်ရင် shared history ကို ပြန်ရေးပစ်ပြီး သူတို့ clone ကို ချိုးဖျက်ပစ်ပါလိမ့်မယ်။
`git reset --hard` က confirmation တစ်ခုမှ မတောင်းဘဲ staged/unstaged ပြောင်းလဲမှုတွေကို ဖျက်ပစ်ပါတယ်၊ ပြန်ယူရတာလည်း မလွယ်ကူပါဘူး — `git status` ကို အရင် အမြဲ ကြည့်ပါ။
အမြန်စစ်ဆေးမှု: Shared Commit တစ်ခုကို ပြန်ဖျက်ခြင်း
Git Documentation: git-revert — Git & GitHub