챗GPT 데이터 사이언스

4주차: Git/GitHub

버전 제어 Git/GitHub을 학습합니다.

저자
소속

1 GitHub

GitHub는 클라우드 기반의 호스팅 서비스다. 이를 통해 사용자들은 자신들의 작업을 저장하고 추적할 수 있으며, 이를 ’버전 관리’라고도 부른다. 인터넷을 통해 요청에 따라 리소스를 제공하는데, 이 중 하나가 저장 공간이다. 이 덕분에 사용자는 로컬에 큰 파일들을 저장하지 않아도 된다. GitLab이나 BitBucket과 같이 GitHub와 유사한 서비스들도 있다라고 말할 수 있다.

1.1 사용사례

GitHub는 다양한 사용 사례를 가지고 있다.

  • 프로젝트를 저장하는 데 사용된다. 개발자는 GitHub를 이용해 코드를 안전하게 보관하고 필요할 때 언제든지 접근할 수 있다. 또한, GitHub는 프로젝트와 파일을 추적하는 기능도 제공한다. 이는 버전 관리 시스템의 일환으로, 코드의 이전 버전을 복구하거나, 특정 시점에서의 코드 변화를 확인하는 것이 가능하다.

  • GitHub는 다른 사람들과 협업하는데도 사용된다. 다른 사용자와 함께 코드를 수정하고 개선하며, 이 과정에서 발생하는 모든 변경사항을 추적한다. 이로써, 팀 프로젝트를 진행하거나 여러 개발자가 동시에 같은 프로젝트에 참여하는 경우에 매우 유용하다.

  • GitHub는 사회적 네트워크의 형태를 띠기도 한다. 개발자들은 서로의 프로젝트를 볼 수 있고, 코드를 공유하며 서로의 작업을 평가하고 피드백할 수 있다. 이는 코드의 질을 향상시키고, 새로운 아이디어나 해결책을 발견하는 데 도움을 준다.

  • GitHub는 오픈 소스 프로젝트를 위한 플랫폼으로 널리 알려져 있다. 개발자들은 자신의 프로젝트를 공개적으로 공유하여, 다른 사람들이 그 프로젝트에 기여하거나, 자신의 프로젝트에서 사용할 수 있게 한다. 이로 인해, 전 세계의 개발자들이 자신의 아이디어와 코드를 공유하며, 서로 협력하는 글로벌 커뮤니티를 형성하게 된다라고 설명할 수 있다.

1.2 Git/GitHub 비교

Git은 리누스 토발즈가 개발한 분산 버젼 제어 관리 시스템이고, GitHub은 Git을 기반으로 한 협업 시스템이다.

Git GitHub
정의 분산 버전 관리 시스템 클라우드 기반 호스팅 서비스
목적 코드의 변경사항을 추적하고 협업 코드 호스팅, 버전 관리, 협업, 오픈 소스 프로젝트 공유
오프라인 작업 예, 로컬에서 작동 아니요, 인터넷 연결 필요
협업 로컬 네트워크를 통한 협업 가능 웹 기반 서비스로 전세계 개발자들과 협업 가능
인터페이스 주로 커맨드라인 인터페이스 웹 인터페이스와 그래픽 사용자 인터페이스 제공

1.3 GitHub 저장소

Git/GitHub은 로컬과 원격 저장소라는 차이만 존재하고 프로젝트에 대한 다음 정보를 담고 있다는 점에서 동일하다.

  • 파일(데이터, 디렉토리 포함)
  • 과거 변경이력(.git/)

1.4 (비) 공개 저장소

GitHub 저장소를 공개와 비공개로 정할 수 있다.

1.5 PAT 설정

$ git clone https://github.com/statkclee/2015-02-25-seoul.git
Cloning into '2015-02-25-seoul'...
Username for 'https://github.com': tidyverse
Password for 'https://tidyverse@github.com':
remote: Enumerating objects: 897, done.
remote: Total 897 (delta 0), reused 0 (delta 0), pack-reused 897
Receiving objects: 100% (897/897), 258.85 KiB | 9.59 MiB/s, done.
Resolving deltas: 100% (521/521), done.
$ cd 2015-02-25-seoul
$ ls
_config.yml       DESIGN.md  img        index.html  LICENSE.md  requirements.txt  tools
CUSTOMIZATION.md  FAQ.md     _includes  _layouts    README.md   setup

1.6 클론과 포크

“클론(Clone)”과 “포크(Fork)”는 Git과 GitHub에서 중요한 개념으로, 원격 저장소의 복사본을 만드는 방식에 차이가 있다.

  • 클론(Clone): 클론은 원격 저장소를 그대로 복사하여 로컬 시스템에 저장하는 것을 의미다. 이를 통해 원격 저장소의 모든 커밋 히스토리와 브랜치 등을 그대로 가져올 수 있습니다. 클론을 이용하면 로컬에서 작업을 시작하고, 그 결과를 다시 원격 저장소에 푸시하여 작업을 공유할 수 있고, 원본 저장소에 변경사항을 적용하려면 write 접근권한이 필요하다.

  • 포크(Fork): 포크는 GitHub에서 특정한 기능으로, 원격 저장소를 복사하여 사용자의 GitHub 계정 내에 새로운 원격 저장소를 생성한다. 이를 통해 원본 프로젝트를 자유롭게 수정하고 개선할 수 있고 포크된 저장소에서의 변경사항은 원본 저장소에 직접 반영되지 않으며, 사용자는 ’Pull Request’를 통해 원본 저장소에 변경사항을 제안할 수 있지만, 원본 저장소에 대한 write 접근권한은 필요하지 않다.

클론(Clone) 포크(Fork)
정의 다른 사람의 프로젝트를 로컬에 복제 다른 사람의 프로젝트를 자신의 GitHub 계정에 복제
목적 프로젝트의 로컬 복사본을 만들어 작업하기 원본 프로젝트에 대한 변경을 제안하거나 개선하기
새로운 저장소 생성? 아니오, 단순히 로컬에 복사본 생성 예, 원본 프로젝트를 기반으로 새로운 리포지토리 생성
협업 원본 저장소에 대한 쓰기(write) 접근권한이 필요 원본 저장소에 대한 쓰기(write) 접근권한이 없어도 가능

1.7 이슈(Issue)

GitHub의 “Issue”는 프로젝트에 대한 버그 리포트, 기능 요청, 질문, 또는 일반적인 토론을 위한 추적 도구입니다. 개발자들은 이슈를 사용하여 프로젝트의 특정 부분에 대해 의견을 주고받거나 문제점을 지적할 수 있다.

  • 문제 추적: 이슈는 프로젝트에서 발견된 버그나 개선점을 관리하고 추적하는 데 사용된다. 각 이슈에는 고유한 번호와 제목이 부여되어, 프로젝트의 특정 부분에 대한 질문이나 문제를 명확하게 지정하고 추적할 수 있다.

  • 협업 도구: 이슈는 프로젝트 참여자들 간의 의사소통 수단으로도 활용된다. 이슈를 통해 프로젝트 참여자들은 서로 대화를 나누고 문제 해결에 대한 아이디어를 공유할 수 있다.

  • 작업 관리: 이슈에는 라벨, 담당자, 마일스톤 등을 지정할 수 있어, 프로젝트의 작업을 효과적으로 관리할 수 있다. 라벨을 이용하면 이슈를 분류할 수 있고, 담당자를 지정하면 특정 이슈의 책임자를 명확히 할 수 있다. 마일스톤을 설정하면 이슈를 특정 목표와 연결시킬 수 있다.

  • 프로젝트 상태 추적: 이슈는 ‘열림’ 또는 ‘닫힘’ 상태를 가진다. 이슈가 해결되면 ‘닫힘’ 상태로 변경되어, 해당 이슈가 처리되었음을 명확하게 표시할 수 있고, 이를 통해 프로젝트의 전체적인 진행 상태를 쉽게 파악할 수 있다.

1.8 풀 요청(Pull Request)

풀요청(PR, ‘Pull Request’)는 GitHub의 핵심 기능 중 하나로, 사용자가 자신이 수정 또는 개선한 코드를 원본 프로젝트에 반영하고자 할 때 사용하는 기능이다. Pull Request를 통해 사용자는 원본 프로젝트의 소유자 또는 관리자에게 자신의 변경사항을 검토하고 병합해달라는 요청을 보낼 수 있다.

  • 포크(Fork): 원본 저장소를 자신의 GitHub 계정으로 포크(fork)한다. 원본 저장소의 전체 복사본이 자신의 계정에 생성된다.

  • Clone and Create a New Branch: 포크된 저장소를 자신의 로컬 시스템으로 클론(clone)한 후, 새로운 브랜치를 만든다. 이 브랜치에서 변경사항을 작업하면 원본 프로젝트의 코드를 안전하게 보호할 수 있다.

  • Make Changes and Commit: 필요한 변경을 만든 후, 이를 커밋(commit)합니다. 커밋 메시지에는 작업 내용을 명확하게 설명해야 한다.

  • Push: 변경사항을 자신의 GitHub 포크 저장소로 푸시(push)한다.

  • Create a Pull Request: GitHub 페이지에서 원본 저장소를 방문하여 “New pull request” 버튼을 클릭한다. 변경하고자 하는 브랜치를 선택한 후, Pull Request의 세부사항을 작성하고 “Create pull request” 버튼을 클릭하여 Pull Request를 제출한다.

  • 원본 저장소의 소유자 또는 관리자는 제출된 Pull Request를 검토하고, 필요하다면 논의를 진행한다. 만약 모든 것이 순조롭다면, 원본 저장소의 관리자는 Pull Request를 수락하고 병합(merge)하여 변경사항을 원본 프로젝트에 반영하게 된다.

2 Git

2.1 버전과 버전제어

버전(Version)이란, 특정 시점에서 파일의 내용을 지칭한다. 이는 소프트웨어나 프로그램, 심지어 문서 등 어떤 유형의 파일에서도 발생할 수 있으며, 파일에 일어난 변화를 시간적 순서에 따라 추적하고 관리하는 데 유용하다. 즉, 특정 시점의 파일 내용과 그와 연관된 정보들을 총체적으로 포함한 상태를 말한다. 이렇게 버전을 통해 파일의 변경사항을 관리하고 추적함으로써, 이전 상태로 롤백하거나 특정 시점의 상태를 참조할 수 있다는 장점이 있다.

버전에는 파일의 내용 외에도 메타데이터라 불리는 추가 정보가 포함될 수 있다. 이 메타데이터에는 파일 작성자, 파일이 위치한 곳, 파일 유형, 마지막으로 저장된 시간 등이 포함될 수 있다. 이러한 메타데이터는 버전 관리 시스템에서 파일의 변화를 효과적으로 추적하고 이해하는 데 중요한 역할을 한다.

버전 제어(Version Control)는 문서, 프로그램, 디렉토리 등의 변경사항을 관리하기 위한 시스템과 과정을 총체적으로 지칭한다. 이는 시간이 지나면서 변화하는 어떤 것에든, 또는 공유해야 하는 어떤 것에든 유용하게 사용될 수 있다. 버전 제어는 프로젝트의 변화를 체계적으로 관리하고 추적하는 동시에, 효과적인 협업을 가능하게 하여 개발자들은 보다 안정적이고 효율적인 개발 환경을 구축하고 유지할 수 있다.

버전 제어 시스템을 사용하면, 파일이나 프로젝트의 각 버전을 명확히 식별하고 추적할 수 있다. 이는 특정 시점의 버전으로 롤백하거나, 다른 버전과의 차이점을 비교하고 병합하는 것을 가능하게 하고, 여러 사용자가 동일한 프로젝트에 동시에 작업할 경우, 각자의 작업을 분리하여 관리하고, 이후 안전하게 병합하는 작업을 가능케 한다.

버전 제어가 중요한 이유를 다음과 같이 요약할 수 있다.

  • 변경사항 추적: 버전 제어 시스템을 사용하면 프로젝트에 대한 수정사항을 시간에 따라 추적할 수 있다. 이는 단순히 무엇이 변경되었는지만 아니라 누가 그 변경사항을 만들었는지, 왜 만들었는지에 대한 정보도 포함한다. 만약 에러가 발생하면, 문제가 언제 어떻게 발생했는지를 확인할 수 있다.

  • 협업: 팀 환경에서는 여러 사람이 동일한 프로젝트에 참여한다. 버전 제어가 없으면 팀원들이 서로의 변경사항을 덮어쓰게 되어 혼란을 초래하고 작업을 잃어버릴 수 있다. 버전 제어를 사용하면 여러 사람이 동시에 프로젝트에 작업을 하더라도 작업을 잃어버리거나 덮어쓰는 일 없이 작업을 할 수 있다.

  • 실수 되돌리기: 실수를 하거나 버그를 도입한 경우, 버전 제어를 통해 코드베이스를 이전 상태로 되돌릴 수 있다. 이는 작은 버그가 큰 영향을 미칠 수 있는 중요한 시스템에서 생명을 구할 수 있는 도구다.

  • 백업 및 복원: 버전 제어 시스템은 모든 변경사항의 복사본을 유지함으로써 백업의 역할을 한다. 데이터를 잃어버리거나 작업이 손상된 경우, 이전 버전의 작업을 복원할 수 있다.

  • 실험: 버전 제어를 사용하면, 개발자들은 새로운 기능이나 아이디어를 실험하기 위해 브랜치를 만들어 기본 코드베이스에 방해를 주지 않고 작업할 수 있다. 새로운 아이디어가 테스트되고 승인되면, 이를 메인 코드베이스로 다시 병합할 수 있다.

2.1.1 Git 장점

Git은 컴퓨터 프로그래밍 및 데이터 프로젝트를 위한 인기 있는 버전 제어 시스템으로 2005년에 리누스 토발즈가 개발했으며, 그의 주요 목표 중 하나는 효율성, 데이터 무결성, 독립적인 작업의 지원 등을 기반으로 한 대형 프로젝트를 위한 완전히 분산된 시스템을 만드는 것이였다. Git은 오픈소스로 소스 코드가 공개적으로 이용 가능하여 누구나 Git의 코드를 가져와서 필요에 따라 수정하거나 개선할 수 있다. Git은 매우 확장 가능한 도구로 작은 프로젝트에서부터 대규모 프로젝트까지 다양한 크기와 복잡성의 프로젝트에서 사용할 수 있다. Git과 GitHub은 다르지만, 함께 사용된다. Git은 버전 제어 시스템이며, 반면에 GitHub는 Git을 기반으로 한 웹 기반의 호스팅 서비스로 GitHub을 통해 Git 기능을 활용하면서 코드를 온라인으로 공유하고 협업하는 기능을 추가적으로 제공한다.

2.1.2 Git 설치

$ git --version
git version 2.30.2

2.2 Git 작업흐름

실제 환경에서는 브랜치 생성, 병합, 충돌 해결 등 추가적인 단계가 있지만, 매우 기본적인 Git 작업 흐름은 다음과 같다.

  1. 작업 영역(프로젝트 디렉토리)에서 변경사항 생성: 로컬 시스템에서 작업을 진행하면서 파일을 수정하거나 새로 생성한다.

  2. 변경사항을 준비영역 추가: git add 명령어를 사용하여 작업 영역의 변경사항을 준비영역(Staging Area)에 추가를 통해 커밋될 변경사항이 준비된다.

  3. 준비영역 변경사항을 로컬 저장소에 커밋: git commit 명령어를 사용하여 메세지 -m과 함께 준비영역 변경사항을 로컬 저장소에 커밋한다. 이 단계를 통해 변경사항이 .git 저장소에 히스토리에 기록된다.

  4. 커밋된 변경사항을 원격 저장소에 푸시: git push 명령어를 사용하여 로컬 저장소의 커밋된 변경사항을 원격 저장소에 푸시한다. 이 작업을 통해 다른 개발자들이 변경사항을 볼 수 있게 된다.

sequenceDiagram
    participant W as 작업 디렉토리<br> Working Directory
    participant I as 준비구역 <br> Staging Area
    participant LR as 로컬 저장소 <br> Local Repository
    participant RR as 원격 저장소 <br> Remote Repository
    W->>I: git add <br/> (준비구역 변경)
    Note over W,I: Staging Changes
    I->>LR: git commit <br/> (로컬 변경)
    Note over I,LR: Committing Changes
    LR->>RR: git push <br/> (원격 변경)
    Note over LR,RR: Pushing Changes    

2.3 git diff

git diff 명령어는 Git에서 파일 변경사항을 확인할 때 사용한다. 특정 파일의 수정 내역, 두 커밋 사이의 차이점, 브랜치 간 차이점 등을 확인할 수 있고, git diff를 통해 여러가지 환경과 상황에서 파일 변경사항을 확인하는 데 도움이 된다.

2.3.1 디렉토리 <—> 준비영역

아직 스테이징하지 않은 변경사항을 보여준다.

$ git diff
graph LR
    subgraph "Case: Changes in Working Directory"
        A[Working Directory] -- "git diff" --> B["Shows unstaged changes"]
    end

2.3.2 준비영역 <—> 로컬 저장소

준비영역과 마지막 커밋 사이의 변경사항 확인하는 경우로 다음 커밋에 반영될 변경사항(즉, 스테이징된 변경사항)을 보여준다.

$ git diff --staged
graph LR
    subgraph "Case: Changes in Staging Area"
        C[Staging Area] -- "git diff --staged" --> D["Shows changes to be committed"]
    end

2.3.3 커밋 <—> 커밋

두 개의 커밋 사이의 변경사항을 확인하는데 사이의 변경사항을 보여준다.

$ git diff <commit_id1>..<commit_id2>
graph TB
    subgraph "Case: Changes between Commits"
        E[Commit1] -- "git diff commit1..commit2" --> F["Shows changes between two commits"]
    end

2.3.4 브랜치 <—> 브랜치

두 개의 브랜치 사이의 변경사항을 확인하는데 사이의 변경사항을 보여준다.

$ git diff <branch_name1>..<branch_name2>
graph TB
    subgraph "Case: Changes between Branches"
        G[Branch1] -- "git diff branch1..branch2" --> H["Shows changes between two branches"]
    end
git diff 독해
$ git diff file1.md
diff --git a/file1 b/file1
index 3f0e8a9..9cce8e0 100644
--- a/file1
+++ b/file1
@@ -1,4 +1,4 @@
-this is the original text
+this is the modified text
 this is an unchanged line
-this is another original line
+this is another modified line

--- a/file1+++ b/file1: 이 줄들은 비교되는 파일들을 나타낸다. a/는 변경 전의 파일을, b/는 변경 후의 파일을 의미한다.

@@ -1,4 +1,4 @@: 이는 “헌크 헤더(hunk header)”라고 부르며, 변경되는 행들의 위치와 범위를 나타냅니다. -1,4는 원본 파일에서 1번째 줄에서 시작해서 4줄이 변경되었음을 의미하고, +1,4는 수정된 파일에서 1번째 줄에서 시작해서 4줄이 변경되었음을 의미한다.

-this is the original text+this is the modified text: -로 시작하는 줄은 삭제된 줄을, +로 시작하는 줄은 추가된 줄을 나타낸다.

2.4 git log

git log 명령은 커밋 이력을 확인하는 데 사용된다. 기본적인 사용법은 git log 혹은 최근 3개를 원하면 git log -n 3를 입력하면 된다. 가장 최근의 커밋부터 시작하여 커밋들이 역순으로 출력된다.

$ git diff file1.md
diff --git a/file1 b/file1
index 3f0e8a9..9cce8e0 100644
--- a/file1
+++ b/file1
@@ -1,4 +1,4 @@
-this is the original text
+this is the modified text
 this is an unchanged line
-this is another original line
+this is another modified line

--- a/file1+++ b/file1: 이 줄들은 비교되는 파일들을 나타낸다. a/는 변경 전의 파일을, b/는 변경 후의 파일을 의미한다.

@@ -1,4 +1,4 @@: 이는 “헌크 헤더(hunk header)”라고 부르며, 변경되는 행들의 위치와 범위를 나타냅니다. -1,4는 원본 파일에서 1번째 줄에서 시작해서 4줄이 변경되었음을 의미하고, +1,4는 수정된 파일에서 1번째 줄에서 시작해서 4줄이 변경되었음을 의미한다.

-this is the original text+this is the modified text: -로 시작하는 줄은 삭제된 줄을, +로 시작하는 줄은 추가된 줄을 나타낸다.

git log 독해
$ git log -n 3
commit 5a6dcd1b2a7e495b7e05641918f3d4f9d5ae8165 (HEAD -> main, origin/main, origin/HEAD)
Author: Your Name <yourname@example.com>
Date:   Fri Jun 30 13:00:00 2023 -0700

    Fix bug in calculation function

commit d6b4c88f2dd6214d5f618b9a22f0e104b3357e68
Author: Your Name <yourname@example.com>
Date:   Thu Jun 29 13:00:00 2023 -0700

    Add new calculation function

commit 0d8d2e64a2aeb9752714b243624969711bb8f1f3
Author: Your Name <yourname@example.com>
Date:   Wed Jun 28 13:00:00 2023 -0700

    Initial commit

commit 5a6dcd1b2a7e495b7e05641918f3d4f9d5ae8165: 커밋의 SHA-1 해시로 커밋을 식별하는 유일한 ID다.

Author: Your Name <yourname@example.com>: 커밋을 수행한 사람 정보

Date: Fri Jun 30 13:00:00 2023 -0700: 커밋이 수행된 시간

Fix bug in calculation function: 커밋 메시지로 커밋이 수행한 변경사항을 요약한다.

2.5 git show

git show 명령은 특정 커밋에 대한 정보를 표시한다. git show index.md 명령은 index.md 파일에 대한 최신 커밋의 세부 정보를 보여주고, 그 커밋에서 파일이 어떻게 변경되었는지를 보여준다.

$ git show index.md
commit 63450dfbda1a560b9a6e5c3a78db5271b6f6e744
Author: Your Name <yourname@example.com>
Date:   Fri Jun 30 13:00:00 2023 -0700

    Update index.md

diff --git a/index.md b/index.md
index 7a8bca5..97c5076 100644
--- a/index.md
+++ b/index.md
@@ -1,4 +1,4 @@
 # Hello, World!
 
-This is the original content.
+This is the updated content.
  • commit 63450dfbda1a560b9a6e5c3a78db5271b6f6e744: index.md 파일을 마지막으로 수정한 커밋의 해시값이다.
  • Author: Your Name <yourname@example.com>: 해당 커밋의 저자다.
  • Date: Fri Jun 30 13:00:00 2023 -0700: 해당 커밋이 만들어진 날짜와 시간이다.
  • Update index.md: 커밋 메시지다.

그 다음은 diff 정보로 커밋이 해당 파일을 어떻게 변경했는지 보여준다.

  • diff --git a/index.md b/index.md: 변경을 비교하는 두 파일의 이름이다.
  • --- a/index.md +++ b/index.md: 비교를 위해 사용하는 두 파일의 버전이다.
  • @@ -1,4 +1,4 @@: 변경이 발생한 라인의 범위를 나타낸다. 첫 번째 파일의 1행에서 4행 사이와 두 번째 파일의 1행에서 4행 사이에서 변경이 있었다.
  • -This is the original content.: 첫 번째 파일에서 제거된 줄이다.
  • +This is the updated content.: 두 번째 파일에서 추가된 줄이다.

2.5.1 git diff/log/show 비교

git log, git show, git diff는 Git에서 제공하는 기능 중 일부이며, 각각 다른 역할을 수행한다.

명령어 설명 출력결과
git log 커밋 히스토리를 조회하는 명령. 가장 최근의 커밋부터 시작하여 역순으로 모든 커밋을 보여주고, 각 커밋의 해시, 작성자 정보, 날짜 및 커밋 메시지가 포함된다.
git show 특정 커밋의 상세 정보를 보여주는 명령. 해당 커밋에서 이루어진 변경사항을 보여주고, 커밋 정보와 git diff 명령의 출력이 모두 포함된다.
git diff 두 커밋 혹은 작업 공간과 스테이징 영역 사이의 차이를 보여주는 명령. 작업 공간에 있는 현재 변경사항과 스테이징 영역 사이의 차이를 보여주고, 두 커밋의 해시를 지정하여 해당 커밋들 사이의 차이를 보는 것도 가능하다.

2.6 Undo 실행취소

Git에서는 몇 가지 방법으로 변경사항을 취소하거나 이전 상태로 되돌릴 수 있다. HEAD~1는 마지막 커밋을 HEAD~2는 마지막에서 두 번째 커밋을 지칭한다.

  1. 작업 디렉토리의 변경 사항 되돌리기: 만약 작업 디렉토리에서 변경한 내용을 되돌리고 싶다면, git checkout -- <file> 명령어를 사용할 수 있다. 이것은 지정된 파일의 변경사항을 마지막 커밋으로 되돌린다. 예를 들어, index.md라는 파일의 변경을 되돌리려면 git checkout -- index.md를 실행하면 된다.

  2. 스테이징된 변경 사항 되돌리기: 변경사항을 스테이징했지만, 이를 되돌리고 싶다면 git reset HEAD <file> 명령어를 사용할 수 있다. 이 명령어는 지정된 파일의 스테이징된 변경사항을 되돌린다. 예를 들어, index.md라는 파일의 스테이징을 취소하려면 git reset HEAD index.md를 실행하면 됩니다.

  3. 마지막 커밋 되돌리기: 만약 최근의 커밋을 취소하고 작업 디렉토리와 스테이지를 그 상태로 유지하려면, git reset --soft HEAD~1 명령어를 사용할 수 있다. 이 명령은 마지막 커밋을 취소하지만 변경 사항은 스테이징된 상태로 남아 있게 된다.

  4. 마지막 커밋 완전히 취소하기: 최근의 커밋을 완전히 취소하고 그 변경사항을 모두 버리려면 git reset --hard HEAD~1 명령어를 사용할 수 있다. 이 명령은 마지막 커밋을 삭제하고 그 변경사항을 작업 디렉토리에서도 삭제한다. 이 명령은 조심스럽게 사용해야 하며, 되돌릴 수 없다.

$ echo "Original Content" > index.md
$ git add index.md
$ git commit -m "Initial commit"

2.6.1 작업 디렉토리의 변경 사항 되돌리기

먼저 현재 작업 디렉토리에서 index.md 파일에 수정작업을 가하자.

$ echo "Modified Content" > index.md
$ git status

On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   index.md

no changes added to commit (use "git add" and/or "git commit -a")

git checkout -- 명령어로 실행취소(undo) 한다.

$ git checkout -- index.md
$ cat index.md
Original Content

2.6.2 스테이징된 변경 사항 되돌리기

git add index.md 명령어로 작업디렉토리에서 변경한 작업을 준비단계 스테이징 영역으로 옮긴다.

$ echo "Modified Content" > index.md
$ git add index.md
$ git status

On branch main
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   index.md

git reset HEAD 명령어로 준비영역에 있던 변경사항을 다시 작업 디렉토리로 회수한다.

$ git reset HEAD index.md
$ git status

On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   index.md

no changes added to commit (use "git add" and/or "git commit -a")

2.6.3 마지막 커밋 되돌리기

git add, git commit 명령어로 로컬 .git 저장소에 변경사항을 기록한다.

$ echo "New Content" > index.md
$ git add index.md
$ git commit -m "New commit"

git reset --soft HEAD~1 명령어로 .git 저장소 변경사항을 준비영역으로 가져온다.

$ git reset --soft HEAD~1
$ git status

On branch main
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   index.md

2.6.4 마지막 커밋 완전히 취소하기

git add, git commit 명령어로 로컬 .git 저장소에 변경사항을 기록한다.

$ echo "New Content" > index.md
$ git add index.md
$ git commit -m "New commit"

git reset --hard HEAD~1 명령어로 .git 저장소 변경사항 뿐만 아니라 파일 변경상태도 원상태로 돌아간다.

$ git reset --hard HEAD~1
$ git status
On branch main
nothing to commit, working tree clean
$ ls
index.md

2.7 복원

index.md라는 이름의 파일은 이미 몇 번의 커밋이 이루어진 이력이 있다고 가정하자. 이전 버전의 파일을 복원하고, 수정하고, 그리고 커밋하는 방법을 살펴보자.

2.7.1 파일 이전 버전 확인

git log 명령어를 사용해서 파일 커밋 이력을 확인한다.

$ git log -- index.md

commit 0f6f25f (HEAD -> main)
Author: User <user@email.com>
Date:   Tue Jun 1 12:00:00 2023

    Change index.md

commit b0d13fe
Author: User <user@email.com>
Date:   Mon May 31 12:00:00 2023

    Add index.md

2.7.2 이전 버전 파일 복원

b0d13fe 커밋의 index.md 파일을 현재 디렉토리에 복원한다.

$ git checkout b0d13fe -- index.md
$ ls
index.md  otherfile.txt
$ cat index.md
# Index
This is the content of the index.md file.

2.7.3 파일 수정 및 커밋하기

파일을 수정한 후 git status로 확인한다.

$ echo "Modified Content" > index.md
$ git status

On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   index.md

no changes added to commit (use "git add" and/or "git commit -a")

$ git add index.md
$ git commit -m "Modified index.md"

git log를 통해 새로운 커밋이 기록되었는지 확인한다.

$ git log -- index.md

commit 2a6d8fc (HEAD -> main)
Author: User <user@email.com>
Date:   Wed Jun 2 12:00:00 2023

    Modified index.md

commit 0f6f25f
Author: User <user@email.com>
Date:   Tue Jun 1 12:00:00 2023

    Change index.md

commit b0d13fe
Author: User <user@email.com>
Date:   Mon May 31 12:00:00 2023

    Add index.md
저장소 청수

git clean -n 명령어를 통해서 git 추적되지 않는 파일을 확인할 수 있다.

$ git clean -n

git clean -f 명령은 git 추적이 되지 않는 파일을 삭제시킨다.

$ git clean -f

2.8 git branch/merge

2.9 git pull/push

2.10 git config