Thuta Learning
Git & GitHub: Collaboration and Professional Workflows
IntermediateDevOps & Toolsintermediate

Revert နှင့် Reset: ဘေးကင်းစွာ ပြန်ပြင်ခြင်း

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Revert နှင့် Reset: ဘေးကင်းစွာ ပြန်ပြင်ခြင်း concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • Diagram ကို ဖတ်ပြီး Git/GitHub workflow ထဲမှာ state (သို့) data ဘယ်လိုစီးဆင်းသလဲ ခြေရာခံနိုင်ရန်
  • ကိုယ့် project/team အတွက် ဘယ်လို အသုံးချသင့်သလဲ ဆုံးဖြတ်နိုင်ရန်

နားလည်ထားရမယ့် အချက်

`git reset` နဲ့ `git revert` နှစ်ခုစလုံးက ပြောင်းလဲမှုတွေကို ပြန်ဖျက်ပေမယ့် history ကို ကိုင်တွယ်ပုံ ဆန့်ကျင်ဖက်ပါ။ Reset က branch pointer ကို နောက်ပြန်ရွှေ့ပြီး history ကို တိုစေပြီး၊ Revert ကတော့ ရှိပြီးသား commit ကို မထိဘဲ ဆန့်ကျင်ဖက် commit အသစ်တစ်ခု ဖန်တီးပေးပါတယ်။

ToolHistory ဘာဖြစ်လဲ
resetBranch pointer ကို နောက်ပြန်ရွှေ့သည်၊ နောက်ပိုင်း commit များ ချွတ်ထွက်ပြီး history တိုသွားသည်
revertCommit တစ်ခုကို ပြန်ဖျက်ပေးသည့် 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 ပါတယ်။
text
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ပြောင်းလဲမှု ဘယ်ရောက်လဲ
--softStaged, ပြန် 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 ပြီး ဘာတွေ ဆုံးရှုံးတော့မလဲ ကြည့်ပါ။

အတူတူ စမ်းရေးကြည့်မယ်

bash
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
You should see
$ 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 တစ်ခုကို ပြန်ဖျက်ခြင်း

Commit ဆိုးတစ်ခု push လုပ်ပြီးသား ဖြစ်ပြီး teammate တွေက pull ယူသွားပြီဆိုပါစို့။ ဒါကို ပြန်ဖျက်ဖို့ ဘာကို သုံးသင့်လဲ။

Git Documentation: git-revertGit & GitHub

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • Push လုပ်ပြီး တစ်ယောက်ယောက် pull ယူသွားပြီးသား commit တွေအပေါ် `git reset --hard` (သို့ reset ပြီးနောက် force-push) သုံးလိုက်ရင် shared history ကို ပြန်ရေးပစ်ပြီး သူတို့ clone ကို ချိုးဖျက်ပစ်ပါလိမ့်မယ်။
  • `git reset --hard` က confirmation တစ်ခုမှ မတောင်းဘဲ staged/unstaged ပြောင်းလဲမှုတွေကို ဖျက်ပစ်ပါတယ်၊ ပြန်ယူရတာလည်း မလွယ်ကူပါဘူး — `git status` ကို အရင် အမြဲ ကြည့်ပါ။
  • Destructive (သို့) history ပြောင်းလဲနိုင်တဲ့ command တိုင်းကို run မခင် git status နဲ့ လက်ရှိအခြေအနေကို အမြဲစစ်ပါ။

လေ့ကျင့်ခန်း

Scratch repo မှာ commit နှစ်ခု လုပ်ပါ။ ဒုတိယ commit ကို `git revert` နဲ့ ပြန်ဖျက်ပြီး `git log --oneline` နဲ့ history က တိုသွားခြင်းမဟုတ်ဘဲ တိုးလာခြင်းဖြစ်ကြောင်း အတည်ပြုပါ။ ပြီးရင် သီးခြား scratch repo မှာ ပြန်ချေဖျက်ရမယ့် commit တစ်ခု လုပ်ပြီး၊ reset mode သုံးမျိုးလုံးကို အစဉ်လိုက် စမ်းကြည့်ပါ (`--soft`, ပြီးရင် plain `git reset HEAD` နဲ့ unstage လုပ်ခြင်း) — တစ်ခုစီပြီးတိုင်း `git status` run ပြီး ဘာအတိအကျ ပြောင်းသွားလဲ မှတ်သားပါ။

You'll know it worked when: $ 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")

Revert နှင့် Reset: ဘေးကင်းစွာ ပြန်ပြင်ခြင်း | Thuta Learning