[TIL] 2025-07-18 git stash drop 되살리기

H Kim·2025년 7월 18일
0

TIL

목록 보기
76/76
post-thumbnail

ㅎ ㅏ...
잠깐 버그 고쳐야 해서 하던 거 stash 해 놓고 작업한 다음 돌아와서는 git stash pop 을 쳐야 되는데 git stash drop stash@{0} 을 쳐버려서 날려버렸다... OTL...
아니 진짜... 이거 너무 헷갈리지 않니?! 나만 이런 거니!?
정말 가끔 한 번씩 pop도 나오는 거고 drop도 나오는 거니까 헷갈릴 때가 있어... ㄱ-... 어쨌든...
다시 코드 칠려면 칠 수도 있을 정도의 양이었지만 또 치는 게 간단하지는 않은 약간 귀찮은 작업이라서 얘를 살려보기로 했다.
취업하고 나서 2-3달 정도 됐을 때 그 기간 동안 작업했던 거 지웠어서 ㄴㅇㅁㅇㄱ!!! 했던 거 사수가 복구해 준 적이 있었어가지고 할 수 있는 건 알고 있었다.
물론 그 때의 사수분은 그냥 해 주시기만 하고 어떻게 했는지 자세히는 알려주지 않으셔서 몰라가지고 이번에 알아보자, 하고는 함 해 봤다.
바빠죽겠는데... 일 하기 시러서일까...^^

커서 & 제미나이와 함께하였다.


먼저 아래와 같이 쳐서 온갖 값의 해시를 얻어낸다.

git fsck --unreachable | grep commit

git fsck는 file system check라고 한다.
verify the integrity and connectivity of the object를 하는 명령어이다.

여기에서 --unreachable 옵션을 넣으면 integrity나 connectivity가 끊어져 있는 해시값들을 찾는 거니까 정상적이지 않은 것, 즉 내가 날려버린 무언가가 들어있을 가능성이 크다.
다만 이 해시들의 순서는 딱히 보장되어 있지 않고 기간은 대충 90-100일 정도인 것 같아서... 나는 이걸 하나하나 다 확인해야만 한다...


  • 대충 아래와 같이 나타난다.
Checking object directories: 100% (256/256), done.
Checking objects: 100% (25070/25070), done.
unreachable commit 160005452267ae3cf9e52fd9e3fd770e1fa8288e
unreachable commit 40011e29756d1702be027c4214bb73c336775590
unreachable commit a50182d634cae9f595e0c195129ea45664706c68
unreachable commit 920de0fcc7a9399a5b7e096063b3b1c9a5cfe82e
unreachable commit d014d5a5f8ec8a1cdc43dfef827c10a623f80b77
unreachable commit bc19b4bac5f66da27b32ca434036079f1022f328
unreachable commit 7a202e272062343dc7f3367b5f48ac6ee4ad31d9
unreachable commit 2c240043b943b0a4c591df881f878ec5ba6d1d9c

위의 터미널 값을 복사해다가 형식을 git show --stat [hash] 로 해다가 하나하나 확인하였다...


위의 해시 중에 내가 원하는 브랜치의 데이터 해시는 두 개가 나왔다.
왜 두 개지? 라는 의문과 함께...

  • hash 1
git show --stat  7526021b875a641f8f26335f6b2ceb7ad879f55e

commit 7526021b875a641f8f26335f6b2ceb7ad879f55e
Author: -
Date:   Fri Jul 18 10:55:29 2025 +0900

    index on feature/PROD-19237: c40da0e7 [feature/PROD-19237] 식대 부분 취소 모달 개발 진행 중
(END)
  • hash 2
git show --stat  79d5d542966c789485e3f5e05f3ba11424b1c428

commit 79d5d542966c789485e3f5e05f3ba11424b1c428
Merge: c40da0e7 7526021b
Author: -
Date:   Fri Jul 18 10:55:29 2025 +0900

    WIP on feature/PROD-19237: c40da0e7 [feature/PROD-19237] 식대 부분 취소 모달 개발 진행 중

 .../admin/point-history/sikdae-use/sikdaePartialCancelModal.tsx    | 136 +++++++++++++++++++++++-------
 1 file changed, 106 insertions(+), 30 deletions(-)
(END)

이 다음에는 이걸 restore 하려고 하는데 cherry-pick을 해보라고 하길래 따라했다.
근데 hash1을 cherry-pick 하려고 하니 아무것도 바뀐 게 없다고 하면서 안 됐다. 뫄???

일단 넘어가서 hash2를 cherry-pick 진행했다.

git cherry-pick 79d5d542966c789485e3f5e05f3ba11424b1c428


하지만 되지 않았다.
이게 merge commit이어서 그냥은 할 수 없고 - 옵션을 써야한대서 뫄??? 하지만 어쨌든 해 줘! 하고는 진행했다.

git show --pretty=fuller 79d5d542966c789485e3f5e05f3ba11424b1c428

이건 무엇을 바꼈는지 예쁘게 보는 명령어라고 한다.
이렇게 확인해서 보니까 확실히 hash2는 hash1과는 다르게 내가 복구시키고 싶었던 작업분이 잘 들어있었다.

근데 커서가 아래와 같이 부모가 두 명이 있다면서 어느 부모에다가 합칠 건지를 골라야 한다고 했다.

I can see this is a WIP (Work In Progress) merge commit with two parents. For cherry-picking a merge commit, you need to specify which parent to use with the -m option. Let me check what each parent contains:


I can see that this is a WIP stash merge with enhanced changes to the partial cancel modal. The current HEAD is already at the first parent (c40da0e7), so let me try cherry-picking with -m 1 to apply the stash changes:

git cherry-pick -m 1 79d5d542966c789485e3f5e05f3ba11424b1c428

이렇게 하니까 내가 원하는대로 잘 살려낼 수 있었다!

Perfect! The cherry-pick has been resolved successfully. Here's what happened:
✅ Cherry-pick completed successfully
Issue: The original commit was a merge commit which required the -m option to specify which parent to use
Solution: Used git cherry-pick -m 1 to apply the changes from the WIP stash
Result: The enhanced changes to sikdaePartialCancelModal.tsx have been applied cleanly to your current branch
The new commit 371bfc09 now contains all the WIP improvements including:
Enhanced state management with cancel states
Additional form components and validation
Improved UI with CardDescription and VoneTypography
Better table handling with onCellValueChanged events
Your working tree is clean and ready for continued development. The cherry-pick resolved without any conflicts!


근데 살리는 건 살리는 거고, 왜 이렇게 된 건지?는 잘 모르겠어서 더 질문을 해 봤다.
왜 부모가 2명이 됐냐고 하니까 아래와 같이 대답했다.

The Two-Parent Mystery Explained
The commit 79d5d542 is a merge commit created by git stash. Here's the breakdown:

What happened:
1. You were working on the feature - making changes to sikdaePartialCancelModal.tsx
2. You ran git stash - this saved your uncommitted work
3. Git created a merge commit with two parents:

Parent 1 (c40da0e7):

  • The commit message: "[feature/PROD-19237] 식대 부분 취소 모달 개발 진행 중"
  • This was your current HEAD when you stashed

Parent 2 (7526021b):

  • The commit message: "index on feature/PROD-19237: c40da0e7..."
  • This contains your uncommitted changes that were stashed

Why Git does this:
When you run git stash, Git doesn't just save your working directory changes in a simple commit. Instead, it creates a merge commit that preserves:

  • Your committed work (parent 1)
  • Your uncommitted changes (parent 2)
  • The combined state (the merge commit itself)
    This allows Git to properly restore both your working directory AND any staged changes when you later git stash pop or git stash apply.

The commit message format:
Git's standard format for stash commits, where "WIP" means "Work In Progress".
So you didn't explicitly create a merge commit - Git automatically created it when you stashed your work! This is why cherry-picking required the -m option to specify which parent's changes you wanted to apply.


맨 처음에는 git stash를 하면 그게 자동적으로 merge commit인 것처럼 말을 했는데 이거저거 찾아보니까 git stash는 merge commit이 아니라고 해서 아니라는데? 이러고 물어봤더니 갑자기 사과하면서ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
너가 맞다고 merge commit 아니래ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 이 자식이ㅡㅡ


정수님이랑 이거저거 테스트를 해 본 결과,
git stash를 하면 1번: stash를 한 후의 결과(새 작업분이 사라져 있는 상태), 2번: stash 하기 전의 결과(새 작업분이 포함되어 있는 상태) 이렇게 두 개의 커밋을 남긴다.
평소에는 그냥 이런 상태로 살다가 pop을 하거나 하면 아무런 일 없이 제대로 동작시킬 수 있는데, 이 경우에는 내가 drop을 해 버려서 이 커밋 두 개가 garbage collection으로 넘어갔다.
그런데 정말 신기하게도 1번이 넘어갈 때는 그냥 일반 commit으로 넘어가는데 2번이 넘어갈 때는 얘가 merge commit으로 바뀌어서 넘어간다.
그래서 cherry-pick을 해 올 때는 얘가 merge commit이니까 -m 옵션을 써서 바꿔줘야만 한 것 같다.

휴... 정말 힘드럿따...
그래도 어케저케 살렸다...
git은 정말 위대하다...

0개의 댓글