---
description: Git에서 알게 된 지식을 한 눈에
---

# Git에서 알게 된 지식

## 1. Git tree에 대해서

> 출처 : [Github action으로 Sync Fork 자동화하기 - push 될 때마다](https://velog.io/@charming-l/Github-action%EC%9C%BC%EB%A1%9C-push-%EB%90%A0-%EB%95%8C%EB%A7%88%EB%8B%A4-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-%EC%B5%9C%EC%8B%A0%ED%99%94%ED%95%98%EA%B8%B0to-forked-repo)

처음에는 _"같은 커밋해시로 `push`한다"_, _"`Git tree`를 같게 한다"_ 는 팀원의 말이 잘 이해가 가지 않았고, 덕분에 Git의 구조를 다시 한번 공부하게 되는 좋은 계기가 되었다.

Git은 각 상태들을 스냅샷을 해시값으로 구분하고(`commit`), 이들을 연결하여 하나의 거대한 tree를 구성하는데 이게 history, 즉 `Git tree`가 되는 것이다. Git의 각 커밋들은 이 트리를 구성하기 위해 모든 커밋은 부모 커밋의 포인터를 함께 가지고 있다. 위 링크에서는 <mark style="color:red;">서로 다른 부모를 가리키던 커밋을 강제로 연결하는 것이기 때문에 Orgin repo와 forked repo는 서로 다른 커밋 해시를 갖게 된다.</mark> 하지만 이 방법의 경우 개인 레포를 remote url에 등록하여 커밋 내역을 가져와 Origin repo의 최근 변경사항의 커밋으로 자연스럽게 연결하므로 동일한 `Git tree`를 갖게 된다.

과정이 잘 이해가 안갔던 첫 시도로는 무작정 두 레포의 변경 사항을 merge 해서, 양 레포에 다시 push하면 되나? 싶었다. 하지만 체크아웃시에 토큰을 넣어주지 않으니 merge 할 수 없다는 에러가 떴다...\
덕분에 서로 다른 레포끼리 병합시 사용할 수 있는 `--allow-unrelated-histories` 라는 `git merge` 옵션도 알게 되었지만 이후엔 Merge conflict가 발생한다는 에러로 이어졌다. 팀 레포 기준으로 해야하니까 충돌이 발생한다면 우리 레포로 지정해주는 `-Xours`라는 옵션까지 하나 더 배워갈 수 있었다..



### 정리하자면,

1. **Git의 구조 이해**:
   * Git은 상태를 스냅샷으로 저장하고, 이 스냅샷들은 고유의 해시 값으로 구분됩니다.
   * 각 커밋은 부모 커밋을 가리키는 포인터를 가지고 있으며, 이 포인터들이 연결되어 Git 트리를 형성합니다.
   * Git 트리는 이 커밋들의 연결된 히스토리로 구성됩니다.
2. **Git 트리와 커밋 해시**:
   * Git에서 각 커밋은 고유한 해시 값을 가지며, 이 해시는 커밋의 내용과 부모 커밋에 의해 결정됩니다. 동일한 내용의 커밋이라도 부모 커밋이 다르면 해시 값이 달라집니다. 따라서 서로 다른 저장소에서 동일한 내용을 커밋하더라도 부모 커밋이 다르면 서로 다른 해시 값을 가지게 됩니다.
   * 두 저장소가 동일한 Git 트리를 가지려면, 커밋 내역을 동기화하여 동일한 커밋 해시를 유지해야 합니다.
3. **`--allow-unrelated-histories` 옵션**:
   * 이 옵션은 서로 다른 Git 히스토리를 가진 두 저장소를 병합할 때 사용됩니다. 기본적으로 Git은 서로 관련 없는 히스토리를 병합할 때 경고를 표시하고 병합을 막습니다. 이 옵션을 사용하면 이 제한을 무시하고 병합을 강제할 수 있습니다.
4. **Merge 충돌 해결**:
   * 병합 시 충돌이 발생하는 것은 두 저장소가 동일한 파일을 다르게 수정했기 때문입니다. 이때 `-Xours` 옵션을 사용하면 충돌이 발생한 파일에 대해 현재 체크아웃된 브랜치의 변경 사항을 우선시하여 충돌을 해결할 수 있습니다.
   * 이 옵션은 충돌 해결의 한 방법이지만, 항상 모든 상황에 적합하지 않을 수 있으므로 신중하게 사용해야 합니다.
