ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Gitn] git CLI - 버전관리
    생활코딩/Gitn 2021. 1. 25. 11:14

    저장소 만들기

    # git init 대상 디렉토리(현재 디렉토리라면 .)

    상태 확인

    # git status

    파일 git 버전관리 대상에 포함시키기(staging area로 올리기)

    # git add <file>...
    # git add . // working tree의 모든 파일을 올리고 싶은 경우

    버전 생성(Commit)

    # git commit -m "커밋 메시지"
    # git commit -am "커밋 메시지"  // add 작업 + commit 작업 동시 수행
    /* 새로 추가된 Untracked 파일은 자동으로 add 되지 않으므로 유의 */

    기록 보기

    # git log
    # git log --stat  // 파일 상태도 보고 싶다면
    # git log --name-only  // 파일 목록까지만 보고 싶다면
    # git log --name-status  // 파일 이름과 상태를 보고 싶다면
    # git log -p  // 직전 커밋과 비교해 달라진 점(패치내용)을 보여준다.

    변경내역 보기

    # git diff

    버전 삭제: 특정 시점으로 이동하고, 그 이후 내역 삭제

    # git reset --hard commit-id // 특정 커밋 시점으로 되돌리기, 그 이후의 작업은 전부 날아간다.
    # git reset --sort  // branch 이동
    # git reset  // 디폴트: staging area에서 빼기

    버전 이동

    # git checkout commit-id  // commit id는 log에서 확인 가능
    # git checkout master  // 최신 상태로 되돌리고 싶다면

    *checkout과 reset은 제어하는 것이 HEAD인지, branch인지에 따라 달라진다.

    reset을 하면 이동할 commit 상태로 branch가 변경된다. 해당 commit 이후의 역사는 그 브랜치와 상관없게 되어서 삭제된 효과를 낸다. checkout은 branch는 그대로 놔둔 상태로 위치만 변경된다.

    HEAD가 branch가 아니라 commit을 가리키는 상황을 detached라고 부른다.

     

    inital commit 취소

    *현재 있는 브랜치를 삭제하면 된다. 헤드를 지우고 브랜치를 초기화한다.

    # git update-ref -d HEAD

     

     

    버전 되돌리기

    # git revert commit-id

     

    도움말

    # git 명령어 -help

    버전 관리에서 제외하고 싶은 파일이 있다면 .gitignore 파일의 설정을 이용하자.

    [git-scm.com/book/ko/v2/Git의-기초-수정하고-저장소에-저장하기]

    $ cat .gitignore
    *.[oa]
    *~

    첫번째 라인은 확장자가 “.o” 나 “.a” 인 파일을 Git이 무시하라는 것이고 둘째 라인은 ~ 로 끝나는 모든 파일을 무시하라는 것


    [강의출처] https://opentutorials.org/course/3839

     

    git을 이용하면 파일을 여러 갈래로 나누지 않아도 모든 변경사항을 보존하고, 변경내역에 상세한 해설을 추가할 수도 있다.

     

    설치

    맥/윈도우는 깃 홈페이지(https://git-scm.com)에서 설치파일을 다운로드 받아서 설치하면 된다. 터미널에 git을 입력해서 설치여부를 확인할 수 있다.

    리눅스인 경우 설치파일 대신 다운로드 명령어를 제공한다: git-scm.com/download/linux

     

    나는 우분투 컨테이너를 쓰고 있기에 우분투 명령어를 찾아봤다.

    # apt-get install git

    혹은 PPA를 이용해 최신 버전을 다운로드 받을 수도 있다.

    # add-apt-repository ppa:git-core/ppa # apt update; apt install git

    *PPA: Personal Package Archive의 약자로 개인 패키지 저장소라고 부른다. 위키를 찾아보니 우분투의 공식 패키지 저장소에 없는 서드파티 소프트웨어를 위한 소프트웨어 패키지 저장소라고 한다. 공식 패키지는 우분투 새 버전 출시할 때(보통 6개월) 업데이트 되기 때문에 그전에 최신 버전을 사용하고 싶은 경우에 주로 이용하는 듯. 다만 공식적으로 검증된 패키지가 아니고, 누구나 업로드할 수 있기 때문에 잠재적인 위험(패키지간 충돌 혹은 보안 등)을 잘 고려해서 이용하는 게 좋다.

     

    이번에 처음 들어본 것이라 PPA는 생략하고 기본 방식으로 설치하려고 봤는데, 구름 IDE에서 제공하는 컨데이너에는 git이 이미 깔려있다.

     

    저장소(repository) 만들기

    프로젝트를 git으로 관리하려면 변경내역을 저장할 공간을 만들어주어야 한다.

    터미널에서 init 명령을 입력한다. pwd가 현재 디렉토리라면 .로 위치를 표시해주자.

    # git init .
    // Initialized empty Git repository in /workspace/git/hello-git-cli/.git/

    해당 디렉토리에 .git라는 디렉토리가 생긴다. 이후의 변경내역은 모두 이곳에 저장된다.

     

     

    버전 생성 및 관리

    git으로 관리되는 프로젝트는 크게 3가지로 구성된다. 버전이 저장되는 공간(Repository), 실제 수정 /편집 작업이 이루어지는 공간(Working Tree), Working Tree의 파일 중 버전으로 기록할 파일을 정리해두는 공간(Staging Area).

    버전관리는 Working Tree에서 파일 생성 -> Staging Area에 버전 임시저장 -> Repository로 버전 저장 순으로 이루어진다.

     

    일단 파일을 하나 만들어본다.

    # touch hello1.txt
    # vi hello1.txt
    # cat hello1.txt
    1

    그리고 상태 확인을 해보니, 아직 커밋내역은 없고, 아래처럼 변경사항이 있다는 메시지가 출력된다.

    # git status
    On branch master
    
    No commits yet    // 커밋 내역 없음
    
    Untracked files:  // 추적되지 않은 파일
      (use "git add <file>..." to include in what will be committed)
    
            hello1.txt
    
    nothing added to commit but untracked files present (use "git add" to track)
    

    git의 버전관리 폴더 내에 있는 파일이라도, 직접 버전관리 대상에 포함시켜주지 않으면 그 파일은 관리되지 않는다.

    hello1.txt는 버전관리 지정이 안 되었기 때문에 Untracked files에 표시되고 있다.

     

    아래의 use "git add <files>" ... 메시지에서 관리 파일로 지정하는 명령어를 알려주고 있다.

    git add를 하고 다시 상태창을 확인해본다.

    # git add hello1.txt
    # git status
    On branch master
    
    No commits yet
    
    Changes to be committed:
      (use "git rm --cached <file>..." to unstage)
    
            new file:   hello1.txt
    

    메시지가 바뀌었다. 버전관리 대상파일(to be committed)에 변화가 생겼음을 알려준다.

    이대로 버전 저장하려면 아래처럼 입력하면 된다.

    # git commit -m "Message 1"

    -m은 커밋 메세지(변경사항 메모)를 여기에 적겠다는 명령어다.

    -m을 생략하면 에디터가 열려서 직접 메시지를 편집할 수도 있다. 여러 줄을 작성해야한다면 그게 나을 수도 있다.

    *이때 열리는 기본 에디터를 변경하고 싶다면 git config --global core.editor "에디터명" 명령을 사용하면 된다.

     

    아직 유저 등록을 하지 않았다면 아래 같은 메시지가 뜬다.

    *** Please tell me who you are.
    
    Run
    
      git config --global user.email "you@example.com"
      git config --global user.name "Your Name"
    
    to set your account's default identity.
    Omit --global to set the identity only in this repository.
    
    fatal: unable to auto-detect email address (got 'root@goorm.(none)')

    알려주는 대로 git config --global 설정을 하고나서 다시 커밋을 하면

    # git commit -m "Message 1"
    [master (root-commit) fff4c27] Message 1
     1 file changed, 1 insertion(+)
     create mode 100644 hello1.txt

    무사히 커밋되었다는 메세지가 출력된다. 여기서 다시 status를 보면 noting to commit, working tree clean 메시지가 나온다.

    커밋(버전 업데이트)이후 버전관리 대상에 변동사항이 없었다는 뜻이다.

     

    버전이 잘 기록되었는지 확인해보려면 log를 보면 된다. 작성자, 시간, 커밋메시지를 확인할 수 있다.

    # git log
    Author: hayjo <you@example.com>
    Date:   Sun Jan 24 08:16:31 2021 +0000
    
        Message 1

     

    파일울 수정하면 어떻게 되는지 보자. hello1.txt 파일을 변경하고 status를 확인한다.

    # vi hello1.txt
    # cat hello1.txt
    1
    2
    # git status
    On branch master
    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:   hello1.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")

    Working Tree에서 수정된 파일이 Staging Area에 임시저장되지 않았다(Changes not staged)고 나온다.

    여기서 git add를 하면 임시저장을 할 수 있고, 다시 commit을 하면 새 버전이 생성된다.

     

    여러 개의 파일을 수정하는 경우가 있을 수 있다. 파일 2개를 편집하고 status를 확인한다.

    # vi hello1.txt
    # vi hello2.txt

    hello1.txt은 이전에 한 번 add했던 파일이고, hello2.txt는 이번에 처음 생성한 파일이다.

    # git status
    On branch master
    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:   hello1.txt
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    
            hello2.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")

    모든 파일이 백업되어야 하는 것은 아니고, 백업되어서는 안 되는 파일(db 비밀번호 파일 등)도 있기 때문에, 새로 파일이 생성되면 관리하지 않는(Untracked) 상태가 기본값이다. 공유하고 싶지 않다면 이대로 두면 된다.

     

    만약 현재 working tree의 모든 파일을 staging area에 올리고 싶다면 .을 쓰자.

    특정 디렉토리명을 입력하면 해당 디렉토리에 속하는 몯느 파일이 올라간다.

    # git add .

    그리고 다시 status를 보면, 이전에 관리되었던 hello1.txt은 modified, 새로운 파일인 hello2.txt는 새로 생성되었음을 알려준다.

    # git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
            modified:   hello1.txt
            new file:   hello2.txt

     

    다시 커밋을 완료하고 로그를 본다.

    commit 7cc599dd9bbbe7ac4346bd33c9a87a6c13b72904 (HEAD -> master)
    Author: 
    Date:   Sun Jan 24 08:46:38 2021 +0000
    
        Meesage 2
    
    commit fff4c274cecd3f45792086cb4799ccdda71afdc2
    Author: 
    Date:   Sun Jan 24 08:16:31 2021 +0000
    
        Message 1

    로그에는 어떤 커밋이 어떤 파일을 다루고 있는지에 대한 정보가 없다. log 출력시에 --stat 옵션을 주면 확인할 수 있다.

    # git log --stat
    commit 7cc599dd9bbbe7ac4346bd33c9a87a6c13b72904 (HEAD -> master)
    Author: 
    Date:   Sun Jan 24 08:46:38 2021 +0000
    
        Meesage 2
    
     hello1.txt | 2 ++   // 2줄이 추가되었다
     hello2.txt | 3 +++  // 3줄이 추가되었다
     2 files changed, 5 insertions(+)
    
    commit fff4c274cecd3f45792086cb4799ccdda71afdc2
    Author: 
    Date:   Sun Jan 24 08:16:31 2021 +0000
    
        Message 1

     

    다시 파일을 수정하고, 이번에는 차이점을 비교해보기로 한다.

    # git status
    On branch master
    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:   hello1.txt
    

    이렇게 수정된 상태에서 git diff를 하면

    # git diff
    diff --git a/hello1.txt b/hello1.txt
    index 01e79c3..c33d498 100644
    --- a/hello1.txt
    +++ b/hello1.txt
    @@ -1,3 +1,4 @@
     1
     2
    -3
    +four

    친절하게 working tree의 마지막 버전과 비교해서 어느 부분이 추가되고(+four) 삭제되었는지(-3) 표시해준다!

    수정된 부분을 확인할 수 있기 때문에, 마지막 검토에 요긴하게 쓰인다.

     

    검토결과 이 작업부분은 초기화해야겠다는 판단이 선다면 git reset을 쓰면 된다.

    다만 reset + 특정 버전은 그 버전을 삭제하는 게 아니라, 그 버전이 되겠다는 뜻임에 유의하자.

    커밋을 총 3번 했고, 이중 2번째 커밋으로 reset을 한 경우, 현재 상태는 2번이고 2번 이후의 모든 커밋이 사라진다.

    git reset --hard commit-id

    hard 옵션 외에 다른 옵션을 쓰고 싶다면 git reset -help 로 보면 된다.

     

    reset이 부담스럽다면 revert가 있다. revert는 특정 커밋을 취소하는 커밋을 발행하는 명령이다.

    정확히는 커밋 자체가 아니라 그 커밋에서 발생한 변화를 취소하는 것이라서, revert 하고나면 이전 소스코드로 구성된 새 커밋이 생긴다.

     

    혹시 커밋을 3번 했을 때, 이중 2번째 커밋만을 revert한다면 현재 최신인 3번과 2번이 revert 된 상태 사이에 충돌이 생길 수 있다.

    이런 경우 역순으로 그 이전 커밋을 모두 revert(3번째 커밋 revert -> 2번째 커밋 revert) 해야 한다.

     

     

     

     

    버전 이동: checkout

    reset, revert 외에도 checkout이 있다. HEAD를 변경하는 방법으로 시간여행을 해보자.

    먼저 log를 통해 과거로 돌아가고 싶은 커밋 아이디를 확인한 다음, checkout commit-id를 입력하면 된다.

    commit 7cc599dd9bbbe7ac4346bd33c9a87a6c13b72904 (HEAD -> master)
    Author:
    Date:   Sun Jan 24 08:46:38 2021 +0000
    
        Meesage 2
    
    commit fff4c274cecd3f45792086cb4799ccdda71afdc2  // commit id
    Author: 
    Date:   Sun Jan 24 08:16:31 2021 +0000
    
        Message 1
    # git checkout fff4c274cecd3f45792086cb4799ccdda71afdc2
    
    Note: checking out 'fff4c274cecd3f45792086cb4799ccdda71afdc2'.
    
    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by performing another checkout.
    
    If you want to create a new branch to retain commits you create, you may
    do so (now or later) by using -b with the checkout command again. Example:
    
      git checkout -b <new-branch-name>
    
    HEAD is now at fff4c27 Message 1

    현재 상태와 (detached HEAD) 브랜치에 관해서 안내문을 보여주고, 과거의 상태로 돌아왔다.

    이 상태에서 다시 로그를 보면, 기존에 출발했던 Message 2 커밋은 사라져있다. (지워진 것은 아니다.)

    # git log
    commit fff4c274cecd3f45792086cb4799ccdda71afdc2 (HEAD)
    Author: 
    Date:   Sun Jan 24 08:16:31 2021 +0000
    
        Message 1

    맨처음 출발했던 최신 상태로 되돌아가고 싶다면 commit-id에 master를 입력하면 된다.

    # git checkout master
    Previous HEAD position was fff4c27 Message 1
    Switched to branch 'master'

     

    댓글

Designed by Tistory.