[TIL] Git 내부 작동과 깊은 복사

krkorklo·2022년 8월 24일
0

TIL

목록 보기
10/29
post-thumbnail

Git의 내부

  • Git의 핵심은 단순한 Key-value 데이터 저장소
  • 어떠한 형식의 데이터라도 집어넣을 수 있고 해당 key로 언제든지 데이터를 가져올 수 있음

Git 개체

  1. git init으로 저장소 생성
  2. .git/objects, .git/objects/info, .git/objects/pack 디렉토리가 생성
    • pack 폴더 아래에 오브젝트를 압축한 바이너리 파일과 무엇이 압축되었는지 기록하는 index 파일이 생성
  3. 파일이 생성되면 .git/objects/{hash} 이름으로 파일, tree, commit이 생성

Blob

  • 파일을 위한 Object로 git add 할 때 생성
  • 파일 내용이 들어있고 파일명에 대한 정보는 없음

Tree 개체

  • git commit 할 때 생성
  • Tree 개체에 파일 이름, blob의 해시값, 다른 tree의 해시값 저장
  • Tree는 디렉토리, Blob은 일반 파일, Inode에 대응
  • Tree 개체 하나는 여러 항목을 가질 수 있다
  • 각기 다른 스냅샷을 나타냄

Commit 개체

  • git commit 할 때 생성
  • Tree 개체를 불러오려면 해싱된 값을 기억해야하는 어려움 → 스냅샷을 누가, 언제, 왜 저장했는지 정보는 커밋 개체에 저장
  • 커밋 개체는 해당 스냅샷에서 최상단 Tree를 하나 가리킴
  • 새 커밋 개체는 스냅샷을 가리키는 Tree 개체를 하나씩 가리킴
  • Blob, Tree, commit 개체는 모두 .git/objects 디렉토리에 저장

Tag

  • git tag 할 때 생성
  • commit명, tag, message 등이 기록

Git Branch

  • git branch는 .git/refs/heads에 branch 디렉토리로 존재
  • branch 디렉토리 내에 가리키는 commit hash 존재
  • 처음 git init 했을 때는 heads에 데이터 없음!
  • 현재 브랜치가 무엇인지에 대해서는 .git/HEAD 파일에 명시
  • commit 없이 브랜치 생성하면 .git/HEAD에 명시되어 있지만 .git/refs/heads에는 값이 없음
  • git checkout할 시 .git/HEAD의 내용이 변경!

Git Merge

  • 현재 브랜치가 가리키는 commit과 병합할 브랜치가 가리키는 commit, 이 두 객체가 공통으로 물려받은 조상 commit을 3 way-merge방식으로 병합

깊은 복사와 얕은 복사

깊은 복사

  • 실제 값을 새로운 메모리 공간에 복사
  • JSON.stringify() & JSON.parse() : 객체를 json 문자열로 변환하고 JSON.parse()를 사용해 객체로 만들어주는 깊은 복사 (하지만 속도가 느리고 함수는 복사할 수 없음)
  • Lodash - clonedeep : 깊은 복사 및 함수 복사도 가능

얕은 복사

  • 주소값을 복사
  • 참조하고 있는 값은 같기때문에 복사된 값을 수정하면 기존 값에도 수정사항이 반영
  • Array.prototype.slice() : start와 end값을 설정하지 않으면 기존 배열을 얕은 복사
  • Object.assign() : 1차원 객체에는 깊은 복사, 2차원 객체는 얕은 복사
  • Spread
    • 1차원 객체에서만 깊은 복사, 2차원 객체는 얕은 복사

    • 원본 주소와 참조를 끊어주기 위해서 새로운 주소값에 값을 할당하면 깊은 복사

      let obj = { a: "안녕하세요?" };
      let obj2 = { ...obj, a: "반갑습니다." };
      
      console.log(obj); // { a: "안녕하세요?" };
      console.log(obj2); // { a: "반갑습니다?" };

원시값

  • 기본 자료형으로 Number, String, Boolean, Null, Undefined등이 있다
  • 원시값을 복사하면 그 값은 또다른 독립적인 메모리 공간에 할당되어 깊은 복사가 일어난다

참조값

  • 여러 자료형으로 구성되는 메모리에 저장된 객체로 Symbol, Object가 있다
  • 변수에 객체를 저장하면 독립적인 메모리 공간에 값을 저장하고 변수에 저장된 메모리 공간의 참조를 저장 → 변수를 조작하는 것은 해당 객체의 참조값을 조작하는 것
  • 참조값을 복사하면 복사된 변수는 기존 변수와 같은 참조를 가리키고 있어 복사된 변수를 변경하면 기존 변수에도 영향을 끼치는 얕은 복사가 일어난다

참고자료
https://git-scm.com/book/ko/v2/Git의-내부-Git-개체
https://git-scm.com/book/ko/v2/Git의-내부-Git-Refs
https://storycompiler.tistory.com/7
https://coding-groot.tistory.com/68
https://xzio.tistory.com/1024
https://velog.io/@recordboy/JavaScript-얕은-복사Shallow-Copy와-깊은-복사Deep-Copy

0개의 댓글