`git pull`은 내 숙제를 어떻게 먹었습니까?


53

나는 교장실에있는 한 아이가 개가 숙제를하기 전날 밤 숙제를 먹었다 고 설명하지만 얼굴에 미친 데이터 손실 버그를 쳐다보고 있는데 어떻게 된 것인지 알 수 없습니다. git이 어떻게 저장소 전체를 먹을 수 있는지 알고 싶습니다! 나는 자식을 여러 번 꿰 뚫었 고 결코 깜박이지 않았습니다. 나는 그것을 사용하여 20 Gig Subversion 저장소를 27 git repos로 나누고 엉망을 풀기 위해 foo를 필터링했습니다. Reflog는 항상 폴백합니다. 이번에는 카펫이 사라졌습니다!

내 관점에서, 내가 한 모든 것은 실행 git pull되고 전체 로컬 저장소를 손상시켰다. 나는 그것이 "체크 아웃 된 버전을 엉망으로 만들었다"또는 "내가 있던 지점"또는 이와 유사한 것을 의미하지는 않는다. 모든 것이 사라 졌음을 의미 합니다 .

사건에 대한 내 터미널의 스크린 샷은 다음과 같습니다.

사건 스크린 샷

그 과정을 안내해 드리겠습니다. 내 명령 프롬프트에는 현재 git repo (prezto의 vcs_info 구현 사용)에 대한 데이터가 포함되어 있으므로 git repo가 ​​사라진 시점을 확인할 수 있습니다. 첫 번째 명령은 충분히 정상입니다.

  » 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 repo에 있지 않다는 것을 알리기 위해 다른 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 config의 몇 가지 tidbits입니다.

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

예를 들어 git pull, 병합 대신 항상 리베이스를 수행하도록 설정했기 때문에 위 출력의 일부가 정상입니다.

데이터를 복구 할 수 있습니다. 다른 저장소로 푸시되지 않은 중요하지 않은 스태 이스 이외의 자식 객체는 없다고 생각하지만 어떤 일이 있었는지 알고 싶습니다 .

나는 확인했다 :

  • dmesg 또는 시스템 저널의 메시지 원격으로 관련된 것도 없습니다.
  • 드라이브 또는 파일 시스템 오류가 표시되지 않습니다 (LVM + LUKS + EXT4 모두 정상으로 보입니다). 잃어버린 + 발견에는 아무것도 없습니다.
  • 나는 다른 것을 달리지 않았다. 위에 표시되지 않은 기록에는 아무것도 없으며이 기간 동안 다른 터미널이 사용되지 않았습니다. rm잘못된 CWD 등에서 실행되었을 수있는 명령 이 없습니다 .
  • 다른 디렉토리에서 다른 자식 저장소를 파고 들면 git pulls를 실행하는 명백한 이상이 없습니다 .

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


4
@ 패트릭 내가 이미 질문에서 설명한 것처럼 .git존재하지 않습니다. 아무것도하지 않습니다. git root 디렉토리였던 것은 전혀 아무것도 없습니다.
Caleb

2
@Alexander 끌어 오기 작업은 정상입니다 (다른 것은 병합이 아닌 리베이스). 강제 업데이트에 대한 알림은 내가 당기는 리포지토리가 로컬 리포지토리가 마지막으로 본 위치와 다른 위치에서 재설정하는 강제 푸시를 가졌음을 나타냅니다. 다른 개발자들이 볼 수있는 공개 지부가 아니라 내 컴퓨터간에 활발하게 개발되고 자주 재기 반화 된 자료를 동기화하기 때문에 이는 정상적인 현상입니다.
Caleb

3
@Caleb 쉘 프롬프트에는 git branch 표시가 포함되어 있습니다. 즉, PS1을 구성하면 로그에 노출되지 않은 git 명령이 포함됩니다. 그들은 주로 그림을 바꿀 수 있고 문제의 근원이 될 수 있습니다. 쉘 프롬프트가 어떻게 형성되는지, 현재 분기를 얻기 위해 어떤 명령이 실행되는지, 그리고 어떻게 리포터를 망칠 수 있는지를 재고해야합니다.
Netch

2
@Caleb git development mailing list에 정말로 물어봐야한다. 버그 보고서로 작성하거나 비공식적으로 요청할 수 있습니다. 어쨌든 동일합니다. git을 잘 아는 일부 개발자가 있습니다. 어쩌면 직감으로 무슨 일이 있었는지 알 수 있습니다. (그렇지 않다면, 그들은 조용히 토론을 따라갈 것입니다.) 그리고 그들은 전에 일어난 일을 알고 있습니다. (Git에 대한 버그를보고하는 "공식적인"방법이 있다고보고)
Volker Siegel

7
@Wildcard 실제로 실제로 무슨 일이 있었는지 알아낼 때 이것에 대한 답을 모 으려고 의미했습니다. 최근에 시스템이 절전 모드에서 해제되었으며 네트워크가 절전 모드로 전환되기 전에 며칠 동안 네트워크가 종료되었습니다. 그 프로세스 어딘가에 나는 시스템에서 무언가를 업그레이드하려고하는 팩맨 프로세스를 실행 중으로 남겨 두었습니다. 간단히 이야기하면 glibc가 업데이트되고 git 바이너리가 덮어 쓰여졌습니다. 그 자체로 갈림길로 인해 한 인스턴스는 다른 인스턴스와 다르고 서로 점심을 먹었습니다. 디렉토리는 실제로 비어있었습니다 (단지 appar가 아니라
Caleb

답변:


6

예, git숙제를 먹었습니다. 그것의 모든.

dd사건이 발생한 후이 디스크 의 이미지를 만들어 나중에 엉망으로 만들었 습니다. 시스템 로그에서 일련의 이벤트를 재구성하면 다음과 같은 상황이 발생했다고 추론합니다.

  1. pacman -Syu이 사건이 발생하기 며칠 전에 시스템 업데이트 명령 ( )이 발행되었습니다.
  2. 확장 된 네트워크 중단으로 인해 패키지 다운로드를 다시 시도하고있었습니다. 인터넷이 부족한 것에 실망한 나는 시스템을 잠들게하고 잠자리에 들었다.
  3. 며칠 후 시스템이 깨어 났고 다시 패키지를 찾아 다운로드하기 시작했습니다.
  4. 이 저장소를 엉망으로 만들기 직전에 패키지 다운로드가 완료되었습니다.
  5. 시스템 glibc 설치가 git checkout및 이후에 업데이트되었습니다 git pull.
  6. git(가) 후 이진 교체있어 git pull시작이 완료되기 전에.
  7. 그리고 일곱째 날에는 git모든 일에서 쉬었다. 그리고 세상을 삭제하여 다른 사람들도 쉬어야했습니다.

나는 이것이 일어나게 된 경쟁 조건이 무엇 인지 정확히 알지 못하지만 작업 중간에 바이너리를 바꾸는 것은 확실히 좋지 않거나 테스트 가능한 / 반복 가능한 조건은 아닙니다. 일반적으로 실행중인 바이너리의 사본은 메모리에 저장되지만 git이상하고 자체 버전을 다시 생성하는 방식에 관한 것입니다. 분명히 모든 것을 파괴하기보다는 죽었어야했지만, 그 일이 일어났습니다.


1
git이 단일 바이너리 대신 differend 명령을 사용하기 때문에 git이 실패했을 수 있습니다. 간단한 자식 당겨 실행 git-fetch, git-rebase또는 git-mergegit gc
Ferrybig

2

삭제 될 파일 경로를 정의하지 못했을 수 있습니다.

귀하의 사례 remove(path)는 주어진 매개 변수가 빈 문자열이기 때문에 OS에서 루트 폴더로 수정 한 (!) 빈 문자열이기 때문에 내 수제 방법으로 루트 폴더를 제거하려고 했을 때 아름다운 날을 상기 시켰습니다 .

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

  1. Rebase 명령이 remove(project_folder + file_path)(의사 코드) 와 같은 파일을 삭제하려고했습니다.
  2. file_path당시에는 어쨌든 비어있었습니다.
  3. 명령은 다음과 같은 것으로 평가되었습니다. remove(project_folder)

1

운이 좋으면 다음 명령으로이 문제를 해결할 수 있습니다.

git reset --hard ORIG_HEAD  

잠재적 인 위험한 변경이 시작되면 git은 ORIG_HEAD의 현재 상태를 숨 깁니다. 그것으로 당신은 병합 또는 리베이스를 취소 할 수 있습니다.

힘내 매뉴얼 : 병합 취소


4
나는 당신이 전체 질문을 읽지 않았다고 생각합니다. 이런 종류의 수정은 git meta-data가 없기 때문에 완전히 의문의 여지가 없습니다 . 이와 같이 재설정을 수행하려면 기존의 .git 디렉토리와 그 안에있는 일부 오브젝트가 필요합니다. 나는 아무것도 없다. 그것은 엉망인 작업 디렉토리 일뿐 만 아니라 더 이상 모든 종류의 저장소가 아닙니다.
Caleb

아, 사과드립니다. 매우 드문 일입니다. git repo가 ​​사라지면 Linux에서 파일을 섀도 잉하고 파일의 fs 백업을하지 않으면 복구 할 수있는 방법이 없다고 가정합니다. 관련이없는 답변을 삭제하겠습니다.
Routhinator

예, 비정상적인 문제라는 것을 알고 있습니다 (그리고 백업이 있습니다). 내 질문은 어떻게 잘못되었는지 ... git 또는 내 파일 시스템 드라이버에서 버그를 어디에서 찾을 수 있는지 또는 이와 같은 작업 중간에 디렉토리를 먹기 위해 지칠 수있는 모든 것입니다.
Caleb

나는 또한 매우 궁금합니다. 내 repos에 이런 일이 일어나기를 싫어할 것입니다.
Routhinator

-1

누군가이 리포지토리를 실행 한 것처럼 git push --force보이며 그 변경 사항을 풀다운했습니다. 저장소를 새로 복제하면 깨끗한 작업 상태로 다시 돌아갑니다.


1
강제 푸시는 마지막 커밋을 다시 기반으로합니다. 그것은 내가 풀린 것이 아니었고 (작업 디렉토리는 더 이상 작업 디렉토리가 아닙니다!) 다시 복제하더라도 아무 의미가 없습니다.
Caleb

4
나는 당신 .git이 강제 푸시로 누군가의 디렉토리를 제거 할 수 있다고 생각하지 않습니다
Grzegorz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.