index.js에 이런 코드가 있어요.
index.js
index.js
코드와 기록 이름은 개념을 설명하기 위한 예시예요. 실제 터미널 출력이 아니에요.
자바스크립트를 실행하는 실습도 아니므로 Node.js나 패키지는 필요하지 않아요.
파일을 저장하는 것만으로는 무엇이 부족할까요?
편집기에서 저장을 누르면 현재 파일 내용이 바뀌어요. 하지만 다음 질문에 답하려면 변경 기록이 필요해요.
시간에 따른 파일의 변경 이력을 관리하는 것을 버전 관리(version control) 라고 해요. Git을 쓰면
index-final.js 같은 복사본을 계속 만드는 대신, index.js를 편집하면서 이력을 남길 수 있어요. 소스 코드뿐 아니라 README 같은 텍스트도 관리할 수 있어요. Pro Git의 버전 관리 설명을 참고해요.
지금 파일, 다음 커밋의 내용, 이미 남긴 기록
파일을 고친 뒤 바로 커밋하는 대신, 먼저git add로 다음 커밋에 담을 내용을 준비해요.
index.js라는 파일명과 Git의 인덱스(index) 는 서로 다른 말이에요. git add index.js는 그 파일의 현재 내용을 인덱스에 반영하는 명령이에요. 파일을 다른 폴더로 옮기지는 않아요.
Git은 무엇이 바뀌었는지 비교할 수 있지만, 왜 바꿨는지는 사람이 커밋 메시지로 남겨야 나중에 판단하기 좋아요.
커밋은 어떤 모습을 기억할까요?
index.js와 README.md를 함께 기록한다고 해볼게요.
각 커밋이 가리키는 그 시점의 프로젝트 상태를 스냅샷(snapshot) 이라고 해요. B에서
README.md를 수정하지 않았어도, B의 프로젝트 상태에는 그 파일이 포함돼요.
스냅샷이라는 말이 커밋할 때마다 모든 파일을 물리적으로 통째 복사한다는 뜻은 아니에요. 변경되지 않은 파일의 데이터는 기존 것을 참조할 수 있어요. Pro Git의 스냅샷 설명은 이 논리적 상태와 저장 방식을 구분해요.
반면 차이(diff) 는 두 상태를 비교한 결과예요. A와 B의 index.js를 비교하면 바뀐 줄은 이렇게 표현할 수 있어요.
index.js
-는 이전 줄, +는 이후 줄을 나타내요. 파일 내용에 들어가는 문자는 아니에요. 스냅샷은 기록된 상태이고, diff는 상태 사이의 비교예요.
실제 Git에서는 A, B, C 대신 커밋 ID로 기록을 구분해요. 이 글의 문자는 이력을 설명하기 위한 표시예요.
저장 버튼을 누르면 커밋도 될까요?
index.js를 console.log("hello git");로 바꾸고 저장해도 새 커밋은 생기지 않아요. 기본적인 기록 흐름은 다음과 같아요.
작업 파일은 작업 트리에 남아요. 이 그림은 파일을 옮기는 경로가 아니라, 인덱스와 이력이 갱신되는 순서예요.
git add는 실행한 시점의 파일 내용을 인덱스에 반영해요. 이후 같은 파일을 더 고쳐도 자동으로 반영되지 않아요. git add 공식 문서에 설명된 동작이에요.
아래 표는 console.log의 문자열만 줄여 적었어요. 마지막 커밋에 "hello"가 있는 상태에서 시작해요.
지금 파일과 방금 커밋한 내용이 다를 수 있어요. 마지막 줄에서
"hello world"로 바꾼 내용은 아직 커밋하지 않은 변경으로 남아요.
인덱스를 사용하면 여러 파일을 수정해도 이번 커밋에 담을 내용을 고를 수 있어요. 코드 수정과 README 수정을 서로 다른 목적으로 했다면 별도 커밋으로 나누어 이유를 남길 수 있어요.
커밋하면 GitHub에도 올라갈까요?
커밋은 먼저 내 컴퓨터의 로컬 저장소에 남아요. 이 기본적인 기록 작업에는 GitHub 계정이나 인터넷 연결이 필요하지 않아요. 다른 사람과 기록을 공유하려면 별도의 저장소와 주고받는 과정이 필요해요. 이렇게 주고받는 상대 저장소를 원격 저장소(remote repository) 라고 불러요. 이 그림에서 커밋을 만드는 일은 왼쪽 저장소 안에서 먼저 일어나요.push는 그 기록을 상대 저장소에 보내는 별도 작업이에요. 동료도 기록을 가져온 뒤 자기 작업과 어떻게 합칠지 판단해야 해요. 가져오자마자 편집 중인 파일이 무조건 덮어써진다는 뜻은 아니에요. Pro Git의 원격 저장소 설명에서 이 흐름을 확인할 수 있어요.
그렇다면 Git과 GitHub는 어떻게 다를까요?
GitHub는 원격 저장소를 둘 수 있는 서비스 중 하나예요. Git을 사용한다고 꼭 GitHub에 올려야 하는 것은 아니에요. GitHub 공식 소개도 Git과 GitHub의 역할을 구분해요.
기록이 있어도 자동으로 해결되지는 않아요
Git이 남겨 주는 것은 코드와 변경을 판단할 근거예요. 어떤 코드가 요구사항에 맞는지는 사람이 결정해야 해요. 동료는 같은 줄을console.log("hi");로, 나는 console.log("hello git");로 고쳤다면 어떤 내용을 남길지 확인해야 해요. Git이 변경을 자동으로 합칠 수 없는 경우에는 충돌을 알려줘요. 자동으로 합쳐졌더라도 프로그램이 의도대로 동작하는지는 별도로 검증해야 해요.
기록과 백업도 구분해야 해요. 커밋이 내 노트북에만 있다면 노트북이 고장 났을 때를 대비한 다른 사본은 아직 없어요. 원격 저장소에 공유하면 사본을 둘 수 있지만, 아직 보내지 않은 로컬 커밋이나 기록하지 않은 변경까지 함께 보호되는 것은 아니에요.
Git에 기록하지 않은 작업까지 언제나 복구할 수 있는 것은 아니에요.
특히 변경을 버리는 명령을 사용할 때는 현재 파일과 기록된 상태를 먼저 확인해야 해요.
Pro Git의 되돌리기 설명도 이 경계를 강조해요.
내 변경은 지금 어디에 있을까요?
마지막으로 세 장면을 구분해보세요.index.js를 수정하고 편집기에서 저장했어요.- 기록할 내용을 골라 커밋했지만, 원격 저장소에는 보내지 않았어요.
- 그 커밋을 원격 저장소에 push했어요.
답과 이유 확인하기
답과 이유 확인하기
첫 번째는 작업 파일을 저장한 상태예요. 새 커밋은 아직 없어요.두 번째는 로컬 저장소에 새 커밋이 생긴 상태예요. 이 커밋을 원격 저장소에 공유한 것은 아니에요.세 번째는 push가 성공해 원격 저장소에도 그 기록을 보낸 상태예요. 동료가 자기 컴퓨터로 가져왔는지는 또 별개의 일이에요.
자, 정리해볼까요?
- 파일 저장은 작업 파일을 바꾸는 일이에요.
- 커밋은 준비한 프로젝트 상태를 로컬 이력에 남기는 일이에요.
- push는 그 기록을 원격 저장소와 공유하는 일이에요.