왜 `git pull`이 내 작업을 먹어치웠나요?

왜 `git pull`이 내 작업을 먹어치웠나요?

마감일 전날 밤에 개가 내 숙제를 먹어버렸다고 교장실에서 설명하는 어린아이가 된 것 같은 기분이 듭니다. 그런데 미친 데이터 손실 오류가 발생하고 어떻게 이런 일이 발생했는지 이해할 수 없습니다. Git이 내 저장소 전체를 어떻게 먹는지 알고 싶습니다! 나는 git으로 여러 번 머리를 긁었지만 결코 깜박이지 않았습니다. 나는 이를 사용하여 20Gig Subversion 저장소를 27개의 git 저장소로 분할하고 여기에서 브랜치 foo를 필터링하여 혼란을 해결했으며 단 한 바이트도 잃지 않았습니다. reflog는 항상 신뢰할 수 있습니다. 이번에는 카펫이 사라졌습니다!

내 관점에서 내가 한 일은 실행뿐 git pull이었고 전체 로컬 저장소가 파괴되었습니다. "체크아웃 버전이 엉망이 됐다"거나 "내가 있던 브랜치" 또는 이와 유사한 것을 의미하는 것은 아닙니다. 내 말은모든 것이 사라졌습니다.

다음은 이벤트가 발생했을 때 내 터미널의 스크린샷입니다.

이벤트 스크린샷

그 내용을 안내해 드리겠습니다. 내 명령 프롬프트에는 현재 git 저장소(prezto의 vcs_info 구현 사용)에 대한 데이터가 포함되어 있어 git 저장소가 언제 사라지는지 확인할 수 있습니다. 첫 번째 명령은 정상입니다.

  » caleb » jaguar » ~/p/w/incil.info » ◼  zend ★ »
❯❯❯ git co master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

거기에서 내가 "zend" 브랜치에 있고 마스터를 체크아웃한 것을 볼 수 있습니다. 여태까지는 그런대로 잘됐다. 다음 명령 앞의 프롬프트에서 분기가 성공적으로 전환되었음을 확인할 수 있습니다.

  » caleb » jaguar » ~/p/w/incil.info » ◼  master ★ »
❯❯❯ git pull
remote: Counting objects: 37, done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 37 (delta 25), reused 0 (delta 0)
Unpacking objects: 100% (37/37), done.
From gitlab.alerque.com:ipk/incil.info
 + 7412a21...eca4d26 master     -> origin/master  (forced update)
   f03fa5d..c8ea00b  devel      -> origin/devel
 + 2af282c...009b8ec verse-spinner -> origin/verse-spinner  (forced update)
First, rewinding head to replay your work on top of it...
>>> elapsed time 11s

그리고 그것은 사라졌습니다. 경과 시간이 10초를 초과하면 다음 프롬프트 전에 경과된 타임스탬프가 출력됩니다. Git은 재생을 되감고 있다는 알림 외에는 출력을 제공하지 않습니다. 완료되었다는 표시가 없습니다.

다음 프롬프트에는 현재 있는 분기 또는 Git 상태에 대한 데이터가 포함되어 있지 않습니다.

나는 그것이 실패했다는 것을 알지 못했고 실수로 다른 git 명령을 실행하려고 시도했고 내가 git 저장소에 없다는 말을 들었습니다. PWD는 변경되지 않았습니다.

  » caleb » jaguar » ~/p/w/incil.info »
❯❯❯ git fetch --all
fatal: Not a git repository (or any parent up to mount point /home)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

주위를 둘러본 후 나는 완전히 비어 있는 디렉토리에 있다는 것을 알았습니다. 아무것도 없습니다. ".git" 디렉토리는 없습니다. 아무것도 없습니다. 비어 있는.

내 로컬 자식 버전은 2.0.2입니다. 다음은 무슨 일이 일어나고 있는지 파악하는 데 관련이 있을 수 있는 내 git 구성의 몇 가지 유용한 정보입니다.

[branch]
        autosetuprebase = always
        rebase = preserve
[pull]
        rebase = true
[rebase]
        autosquash = true
        autostash = true
[alias]
        co = checkout

예를 들어 git pull병합이 아닌 항상 리베이스하도록 설정했기 때문에 위의 출력 부분은 정상입니다.

데이터를 복구할 수 있어요. 일부 중요하지 않은 저장소를 제외하고는 다른 저장소로 푸시되지 않은 git 개체가 없다고 생각합니다.무슨 일이 일어났는지 알고 싶어.

내가 확인한 내용은 다음과 같습니다.

  • dmesg 또는 systemd 로그의 메시지. 관련성이 없습니다.
  • 드라이브 또는 파일 시스템 오류에 대한 표시가 없습니다(LVM + LUKS + EXT4 모두 괜찮아 보입니다). 분실물에는 아무것도 없습니다.
  • 나는 다른 것을 실행하지 않습니다. 위에는 기록이 표시되지 않으며 이 기간 동안 다른 터미널은 사용되지 않았습니다. rm잘못된 CWD에서 명령 등을 실행할 가능성은 없습니다 .
  • 다른 디렉토리의 다른 git repo를 파킹하면 git pull실행에 대한 명백한 예외가 표시되지 않습니다.

여기서 또 무엇을 찾아야 합니까?

답변1

응, git숙제를 먹었어. 모두.

dd사건 이후 이 디스크의 이미지를 만들고 나중에 수정했습니다. 시스템 로그에서 일련의 이벤트를 재구성하면 무슨 일이 일어났는지 추론할 수 있습니다.

  1. pacman -Syu이 사고가 발생하기 며칠 전에 시스템 업데이트 명령( )이 내려졌습니다.
  2. 네트워크 중단이 길면 패키지 다운로드를 다시 시도해야 함을 의미합니다. 인터넷이 부족해서 답답해서 시스템을 잠자기 상태로 두고 잠자리에 들곤 했습니다.
  3. 며칠 후 시스템이 깨어나 패키지를 다시 찾고 다운로드하기 시작합니다.
  4. 이 저장소를 다루기 전에 패키지 다운로드가 완료되었습니다.
  5. 체계glibc이전 과 이후에 설치가 git checkout업데이트되었습니다 git pull.
  6. 바이너리는 시작 후 및 완료 전에 git교체됩니다 .git pull
  7. 일곱째 날에는 git모든 일을 쉬었습니다. 그리고 다른 사람들도 쉬어야 하도록 세상을 삭제했습니다.

나는 전혀 모른다정확히어떤 경쟁 조건이 발생하여 이런 일이 발생하지만 작업 중에 바이너리를 교환하는 것은 확실히 좋지도 않고 테스트 가능/반복 가능한 조건도 아닙니다. 일반적으로 실행 중인 바이너리의 복사본은 메모리에 저장되지만 이는 git이상하며 자체 버전을 재생성하는 방식이 이러한 혼란을 야기한다고 확신합니다. 분명히 모든 것을 파괴하기보다는 죽어야 하지만 그게 전부입니다.

답변2

삭제할 파일 경로를 정의하지 못했기 때문일 수 있습니다.

remove(path)귀하의 사례는 내 홈브류 방법이 루트 폴더를 삭제하려고 시도했고 주어진 인수가 빈 문자열이었기 때문에 OS가 이를 루트 폴더(!)로 수정했던 좋은 날을 생각나게 합니다 .

이것은 비슷한 자식 버그일 수 있습니다. 그래서:

  1. Rebase 명령은 파일(예 remove(project_folder + file_path): 의사 코드) 을 삭제하려고 합니다.
  2. 어쩐지 file_path그 당시에는 비어 있었습니다.
  3. 명령은 다음과 같이 평가됩니다.remove(project_folder)

답변3

운이 좋으면 다음 명령을 사용하여 이 문제를 해결할 수 있습니다.

git reset --hard ORIG_HEAD  

잠재적으로 위험한 변경이 시작되면 git은 현재 상태를 ORIG_HEAD에 저장합니다. 이를 사용하면 병합 또는 리베이스를 실행 취소할 수 있습니다.

Git 매뉴얼: 병합 실행 취소

답변4

git push --force누군가 이 저장소를 실행했고 귀하가 변경 사항을 가져온 것 같습니다 . 새 저장소를 복제해 보세요. 이렇게 하면 다시 깨끗한 작업 상태로 돌아갈 수 있습니다.

관련 정보