본문 바로가기
IT/PROGRAM

[Git] git(깃) 사용법 . 작업 순서대로 명령어 개념잡기

by SidePower 2021. 7. 8.

 

GIT 설치 이후로

처음부터 차례대로 진행하면서 명령어를 통해 사용해 볼게요.

 

 

Git 설치된 걸로 간주하고 진행합니다.

 

Git설치 바로가기

 

 

사용자 등록하기

소스변경 이력을 추적하기 위해 사용자명과 이메일을 등록합니다.

Git 테스트 디렉터리 Git를 만들었습니다.
[sidepower@localhost test]$ mkdir Git
[sidepower@localhost Git]$ pwd
/home/sidepower/test/Git
[sidepower@localhost test]$ ll
합계 0
drwxrwxr-x. 2 sidepower sidepower 6  7월  2 01:34 Git
[sidepower@localhost test]$ cd Git
[sidepower@localhost Git]$ ll
합계 0

 Git 사용자 등록 명령어
사용자 이름(필수)  → git config --global user.name "사용자명"
사용자 이메일(선택) → git config --global user.email "이메일주소"
[sidepower@localhost Git]$ git config --global user.name "sidepower1"
[sidepower@localhost Git]$ git config --global user.email "sidepwer1@git.com"
[sidepower@localhost Git]$

 

 

프로젝트 만들기

Git은 프로젝트(저장소)를 디렉터리(폴더)를 기준으로 생성합니다.

프로젝트 폴더를 만들고 java 소스를 하나 만들었습니다.

[sidepower@localhost Git]$ mkdir git_project1
[sidepower@localhost Git]$ cd git_project1

[sidepower@localhost git_project1]$ vi git_start.java
[sidepower@localhost git_project1]$ ll
합계 4
-rw-rw-r--. 1 sidepower sidepower 124  7월  2 01:45 git_start.java
[sidepower@localhost git_project1]$ cat git_start.java 
public class git_start { 
    public static void main(String[] args){ 
        System.out.println("hello git world .. start!!"); 
    } 
}
[sidepower@localhost git_project1]$ javac git_start.java
[sidepower@localhost git_project1]$ java git_start
hello git world .. start!!

 

 

 저장소(repository) 초기화하기

저장소는 git이 변경이력을 추적하는 공간을 말하며

저장소 초기화는

지정된 디렉터리안의 모든 변화를 git이 계속 추적한다는 것을 지정하는 것입니다.

 저장소 초기화 
명령어 → git init
[sidepower@localhost git_project1]$ git init
/home/sidepower/test/Git/git_project1/.git/ 안의 빈 깃 저장소를 초기화했습니다

 git_project1 디렉터리가 git의 저장소가 되는게 아닙니다.
    git_project1은 추적대상 디렉터리일뿐입니다.
    git 저장소는 어딘가 따로 있습니다.

 .git 디렉터리가 생성된걸 볼수 있어요.
[sidepower@localhost git_project1]$ ls -al
합계 8
drwxrwxr-x. 3 sidepower sidepower  63  7월  2 02:52 .
drwxrwxr-x. 5 sidepower sidepower  58  7월  2 03:31 ..
drwxrwxr-x. 8 sidepower sidepower 166  7월  2 02:53 .git
-rw-rw-r--. 1 sidepower sidepower 438  7월  2 01:46 git_start.class
-rw-rw-r--. 1 sidepower sidepower 124  7월  2 02:43 git_start.java

 저장소 생성과 추적에 필요한 파일들이 많이 생겼네요.
[sidepower@localhost git_project1]$ cd .git
[sidepower@localhost .git]$ ll
합계 24
-rw-rw-r--. 1 sidepower sidepower   19  7월  2 02:52 COMMIT_EDITMSG
-rw-rw-r--. 1 sidepower sidepower   23  7월  2 02:52 HEAD
drwxrwxr-x. 2 sidepower sidepower    6  7월  2 02:52 branches
-rw-rw-r--. 1 sidepower sidepower   92  7월  2 02:52 config
-rw-rw-r--. 1 sidepower sidepower   73  7월  2 02:52 description
drwxrwxr-x. 2 sidepower sidepower 4096  7월  2 02:52 hooks
-rw-rw-r--. 1 sidepower sidepower  225  7월  2 02:52 index
drwxrwxr-x. 2 sidepower sidepower   21  7월  2 02:52 info
drwxrwxr-x. 3 sidepower sidepower   30  7월  2 02:52 logs
drwxrwxr-x. 8 sidepower sidepower   70  7월  2 02:52 objects
drwxrwxr-x. 4 sidepower sidepower   31  7월  2 02:52 refs

 

 

 현재 상태 체크하기

현재 브랜치(branch)가 master라고 하네요.

branch는 현재 추적중인 작업명을 말하며 독립적인 영역입니다.

최초로 저장소 초기화(git init)를 하면 기본적으로 master라는 branch가 생성됩니다.

다른 branch를 만들지 않는다면

git이 추적하는 모든 작업들과 git 명령어는 master를 통해서 수행됩니다.

 

 커밋 (commit)은 지금까지의 모든 변경이력을 저장소에 기록하는 것입니다.

 

아래 보시면 추적하지 않는 파일이 있다고 표시되어 있네요. 

무슨 내용인지 다음 단계에서 알아볼게요.

 git 상태 확인하기
명령어 → git status
[sidepower@localhost git_project1]$ git status
현재 브랜치 master   

아직 커밋이 없습니다

추적하지 않는 파일:
  (커밋할 사항에 포함하려면 "git add <파일>..."을 사용하십시오)
    git_start.class
    git_start.java

커밋할 사항을 추가하지 않았지만 추적하지 않는 파일이 있습니다 (추적하려면 "git
add"를 사용하십시오)

 

 추적하기

git에서 commit하는 단계가 있습니다.

추적 대상인 프로젝트 디렉터리 안에 파일에서 변경사항이 생기면

저장소에 추가되기 전에 중간에 가상영역인 인덱스(=스테이지)에 먼저 저장됩니다.

프로젝트 디렉터리 ▶ 인덱스(스테이지) ▶ Git 저장소(repository)

인덱스에 등록되어 있어야 추적대상이 되고 또 commit을 수행할 수 있습니다.

인덱스에 없는 파일들은 commit을 할수 없습니다.

 인덱스 등록하기
명령어 → git add 파일 또는 디렉토리 지정

[sidepower@localhost git_project1]$ ll
합계 8
-rw-rw-r--. 1 sidepower sidepower 438  7월  2 01:46 git_start.class
-rw-rw-r--. 1 sidepower sidepower 124  7월  2 01:45 git_start.java

 add 뒤에 . 으로 현재 디렉터리를 지정해서 디렉터리안에 모든 파일들이 등록됩니다.
[sidepower@localhost git_project1]$ git add .
[sidepower@localhost git_project1]$

 인덱스 등록 후 상태 확인하기
[sidepower@localhost git_project1]$ git status
현재 브랜치 master

아직 커밋이 없습니다

커밋할 변경 사항:
  (스테이지 해제하려면 "git rm --cached <파일>..."을 사용하십시오)
    새 파일:       git_start.class
    새 파일:       git_start.java
 새 파일: 이라는 라벨로 두개 등록되었네요. ^^

 

 

 저장소(repository) 추가하기

commit(커밋)을 하게 되면 지금까지의 모든 변경이력이 저장소에 추가됩니다.

 

커밋을 하게 되면 이제 저장소에는

최종 소스로 현행화되면서 그동안의 변경이력이 없어지기 때문에

커밋 단위로 버전이 생긴다고 보시면 될 거예요.

 

그리고 commit 작업 수행 시 40자리의 식별ID를 부여받게 됩니다.

나중에도 이 40자리의 식별ID로 commit 작업을 컨트롤할 수 있게 됩니다.

 저장소 추가하기
명령어 → git commit -m "설명"
-m 옵션뒤에 commit에 대한 자세한 설명을 넣습니다.

[sidepower@localhost git_project1]$ git commit -m "project1 Start.." 
[master (최상위-커밋) adec44a] project1 Start.. 
 2 files changed, 6 insertions(+) 
 create mode 100644 git_start.class 
 create mode 100644 git_start.java 

 commit 후에 git 상태 확인
커밋했기때문에 더이상 변경할게 없어 깨끗하네요.
[sidepower@localhost git_project1]$ git status 
현재 브랜치 master 
커밋할 사항 없음, 작업 폴더 깨끗함

 git 로그 확인
git 로그에는 commit 이력이 모두 표시됩니다.
식별ID 40자리 그대로 표시됩니다.
HEAD는 아래부분에서 설명하겠습니다.
[sidepower@localhost git_project1]$ git log
commit adec44a472dbf854530d2119483ba29234264b53 (HEAD -> master)
Author: sidepower1 <sidepwer1@git.com>
Date:   Fri Jul 2 01:59:47 2021 -0400

    project1 Start..
[sidepower@localhost git_project1]$

 

기본 작업은 모두 끝났습니다.

 

 

 

 

이제 정말로 변경이력이 추적되는지 또 저장소에 추가 잘되고

이력이 잘 생기는지 확인해 보겠습니다.

변경 이력 만들기

임의로 java 소스를 변경해 보겠습니다.

 "Git good" 출력되게 한줄 추가했습니다.
[sidepower@localhost git_project1]$ cat git_start.java
public class git_start {
    public static void main(String[] args){
        System.out.println("hello git world .. start!!");
        System.out.println("Git good");
    }
}

 git 상태 확인
소스변경만 하고 바로 상태 확인을 해보니 파일이 수정된걸 감지하네요 .^^
[sidepower@localhost git_project1]$ git status
현재 브랜치 master
커밋하도록 정하지 않은 변경 사항:
  (무엇을 커밋할지 바꾸려면 "git add <파일>..."을 사용하십시오)
  (use "git restore <file>..." to discard changes in working directory)
    수정함:        git_start.java

커밋할 변경 사항을 추가하지 않았습니다 ("git add" 및/또는 "git commit -a"를
사용하십시오)
[sidepower@localhost git_project1]$

 

 

 다시 커밋(commit) 하기

 -a 옵션은 변경된 파일을 포함시키는 의미입니다.
[sidepower@localhost git_project1]$ git commit -am "source add -- Git good"
[master d9ddbf6] source add -- Git good
 1 file changed, 1 insertion(+)
[sidepower@localhost git_project1]$

 커밋 후 상태 확인
[sidepower@localhost git_project1]$ git status
현재 브랜치 master
커밋할 사항 없음, 작업 폴더 깨끗함

 두번째 커밋이라 commit이력이 생겼는지 확인해 봤습니다.
ㅋ 두개가 있네요.
commit 식별ID 40자리도 다르게 생긴걸 확인할수 있네요.
[sidepower@localhost git_project1]$ git log
commit d9ddbf6cb0fad7908b67e41abef29434e8d9ad84 (HEAD -> master)
Author: sidepower1 <sidepwer1@git.com>
Date:   Fri Jul 2 02:13:22 2021 -0400

    source add -- Git good

commit adec44a472dbf854530d2119483ba29234264b53
Author: sidepower1 <sidepwer1@git.com>
Date:   Fri Jul 2 01:59:47 2021 -0400

    project1 Start..
[sidepower@localhost git_project1]$

 HEADadec44a... 처음 commit에 있었는데
이제는 d9ddbf6.. 두번째 commit에 기록되어 있죠.

 

branch HEAD 

독립적인 작업 단위가 branch(브랜치)라고 했습니다.

그리고 git 설치되고 처음 저장소가 만들어질 때 (init)

기본 브랜치인 master가 생긴다고 위에서 간단하게 설명했었습니다.

 

새로운 파일이 추가되거나 변경이 생겨 커밋을 하는 것은

master라는 branch를 통해서만 할 수 있습니다.

 

git 명령어 사용할 때 master라는 이름을 선언한 적은 없지만

위에 자세히 보시면 알게 모르게 git 명령어를 사용할 때마다

master라는 이름이 시작 부분에 모두 들어가 있을 거예요.

 

HEAD는 현재 작업에 사용 중인 branch를 가리킵니다.

HEAD -> master

또 branch는 항상 마지막으로 작업된 commit을 가리킵니다.

한마디로 HEAD는 현재 브랜치의 마지막 커밋을 가리킵니다.

 

 

 이전 버전으로 되돌리기 (checkout)

소스 수정하다가 너무 엉망이 되어

다시 이전 버전으로 되돌리기 싶을때가 있을 거예요.

 

checkout

git checkout 명령어로 독립적인 작업 단위인 branch를 전환할 수 있습니다.

전환 시 해당 branch의 마지막 commit 상태가 됩니다.

 

 다른 branch로 분기하기 위해서는 

명령어 → git checkout 브랜치명

 

 다른 branch로 분기하지 않고

현재 branch의 소스만 마지막 commit 상태로 되돌리기

명령어 → git checkout . 

브랜치명 부분에 . 을 쓰면 됩니다.

 

 간단하게 한줄 추가로 확인해 볼게요.
[sidepower@localhost git_project1]$ cat git_start.java
public class git_start {
    public static void main(String[] args){
        System.out.println("hello git world .. start!!");
        System.out.println("Git good");

        System.out.println("my mistake .. sorry!!");
    }
}

 상태 확인해 보니 수정된게 감지되었네요.
[sidepower@localhost git_project1]$ git status
현재 브랜치 master
커밋하도록 정하지 않은 변경 사항:
  (무엇을 커밋할지 바꾸려면 "git add <파일>..."을 사용하십시오)
  (use "git restore <file>..." to discard changes in working directory)
    수정함:        git_start.java

커밋할 변경 사항을 추가하지 않았습니다 ("git add" 및/또는 "git commit -a"를
사용하십시오)

 checkout 명령어는 마지막 commit 상태로 상태로 되돌립니다.
[sidepower@localhost git_project1]$ git checkout .
Updated 1 path from the index

 이전 커밋상태로 되돌아가서 변경할게 없이 깨끗합니다.
[sidepower@localhost git_project1]$ git status
현재 브랜치 master
커밋할 사항 없음, 작업 폴더 깨끗함

 소스 확인보니 마지막 줄이 사라진걸 확인할수 있네요. 
[sidepower@localhost git_project1]$ cat git_start.java
public class git_start {
    public static void main(String[] args){
        System.out.println("hello git world .. start!!");
        System.out.println("Git good");
    }
}

 

 

 checkout 추가 사용법

checkout 명령어는 마지막 commit 상태로 되돌어 간다고 했죠.

많은 commit들 중에 해당 commit이 어떤 상태인지 확인하고 싶을때가 있을 거예요.

이럴 때 commit 식별ID를 이용해서 해당 commit상태로도 되돌아갈 수도 있습니다.

 처음 commit한 식별ID를 이용해 처음 소스로 되돌리기 
명령어 → git checkout 식별ID
adec44a472dbf854530d2119483ba29234264b53 
40자리의 commit 식별ID를 지정할때
처음부터 유일한 값이 되는 4자리로도 지정할수 있습니다.
[sidepower@localhost git_project1]$ git checkout adec
Note: switching to 'adec'.

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 switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD의 현재 위치는 adec44a project1 Start..

 현재 상태 확인
[sidepower@localhost git_project1]$ git status
HEAD가 다음 위치에서 분리: adec44a
커밋할 사항 없음, 작업 폴더 깨끗함

 최초 소스로 돌아왔네요. ^^
[sidepower@localhost git_project1]$ cat git_start.java
public class git_start {
    public static void main(String[] args){
        System.out.println("hello git world .. start!!");
    }
}

 checkout 커밋식별ID
커밋을 checkout 하게 되면 현재 branch에서 분리되어 버립니다.
advice.detachedHead 라는 메시지가 보이시죠. 
그리고
git status 명령어는 항상 첫줄에 현재 브랜치 master 라고 표시되는데
위에 보시면 다르게 표시되죠. 
HEAD가 다음 위치에서 분리: adec44a
분리되는 현상을 알려주고 있네요. 


해당 커밋 상태 확인하고 다시 master로 돌아가야겠죠. ㅋ
 master 브랜치로 분기하기
[sidepower@localhost git_project1]$ git checkout master
이전 HEAD 위치는 adec44a project1 Start..
'master' 브랜치로 전환합니다

 현재 소스로 되돌아왔어요.^^
[sidepower@localhost git_project1]$ cat git_start.java
public class git_start {
    public static void main(String[] args){
        System.out.println("hello git world .. start!!");
        System.out.println("Git good");
    }
}

 현재 상태 확인
[sidepower@localhost git_project1]$ git status
현재 브랜치 master
커밋할 사항 없음, 작업 폴더 깨끗함

 git 로그 확인
[sidepower@localhost git_project1]$ git log
commit d9ddbf6cb0fad7908b67e41abef29434e8d9ad84 (HEAD -> master)  
Author: sidepower1 <sidepwer1@git.com>
Date:   Fri Jul 2 02:13:22 2021 -0400

    source add -- Git good

commit adec44a472dbf854530d2119483ba29234264b53
Author: sidepower1 <sidepwer1@git.com>
Date:   Fri Jul 2 01:59:47 2021 -0400

    project1 Start..

 

 

 깔끔하게 커밋 위치 변경하고 새로시작하기

이런 경우를 생각해 봅시다.

git을 통해 오랜기간 많은 소스를 관리하면서 엄청 많은 커밋 이력이 있는 상태입니다.

소스를 특정 시점의 이전 버전으로

복잡한 커밋이력도 다 지워 정리하면서 소스도 돌리고 다시 시작하고 싶을 때가 있을 거예요.

 

이럴 때 reset 명령어를 사용할 수 있습니다.

커밋 상태를 되돌릴 때 checkout를 사용했었는데요.

checkout은 브랜치를 분기하면서 이동했지만

reset는 작업 브랜치 안에서 커밋 위치만 변경하는 명령어입니다.

 

정확한 명령어는 git reset --hard 커밋식별ID입니다.

 최초 소스 커밋상태로 reset 하겠습니다.
[sidepower@localhost git_project1]$ git reset --hard adec44a
HEAD의 현재 위치는 adec44a입니다 project1 Start..

 현재 상태 확인
[sidepower@localhost git_project1]$ git status
현재 브랜치 master
커밋할 사항 없음, 작업 폴더 깨끗함

 최초 소스로 돌아갔네요.^^
[sidepower@localhost git_project1]$ cat git_start.java
public class git_start {
    public static void main(String[] args){
        System.out.println("hello git world .. start!!");
    }
}

 git 로그 확인
[sidepower@localhost git_project1]$ git log
commit adec44a472dbf854530d2119483ba29234264b53 (HEAD -> master)  
Author: sidepower1 <sidepwer1@git.com>
Date:   Fri Jul 2 01:59:47 2021 -0400

    project1 Start..

생각해 보면 reset --hard는

지저분 소스와 이력을 깔끔하게 한방에 정리해주는 핫한 명령어지만

잘못 사용하면 돌이킬 수 없는 상황에 직면하게 될 것입니다.

왜냐하면 reset --hard를 사용해 해당 커밋으로 돌아갔다면

내부적으로 삭제되기 때문에 절대로 복원할 수가 없습니다.

꼭 유념하시고 사용하시기 길 바랍니다.

 

 

 처음부터 다시 시작하기

변경 이력이 너무 꼬여서 도저히 회생 불가능해서 

일에 방해가 될 거 같다고 판단될 때가 있어요.^^;;

소스는 그대로 두면서 모든 이력을 싹 다 지워버리고 싶을 때가 있을 거예요.

이럴때 .git라는 저장소 디렉터리를 삭제하면 됩니다.

 

위에서 git init 명령어 수행시 .git 디렉터리가 자동으로 생성된 걸 보셨죠.

이 디렉터리를 삭제하면 커밋 이력만 모두 날아가고

소스는 삭제되거나 변화지 않습니다.

 

.git 디렉터리를 지우고 git init 부터 다시 시작하면 됩니다.

 .git 디렉터리 확인
[sidepower@localhost git_project1]$ ls -al
합계 8 
drwxrwxr-x. 3 sidepower sidepower  63  7월  2 02:43 .
drwxrwxr-x. 3 sidepower sidepower  26  7월  2 01:40 ..
drwxrwxr-x. 8 sidepower sidepower 183  7월  2 02:44 .git
-rw-rw-r--. 1 sidepower sidepower 438  7월  2 01:46 git_start.class
-rw-rw-r--. 1 sidepower sidepower 124  7월  2 02:43 git_start.java

 현재 상태 확인
[sidepower@localhost git_project1]$ git status
현재 브랜치 master
커밋할 사항 없음, 작업 폴더 깨끗함

 .git 디렉터리 삭제
[sidepower@localhost git_project1]$ rm -rf .git

 현재 상태 확인
[sidepower@localhost git_project1]$ git status
fatal: (현재 폴더 또는 상위 폴더 중 일부가) 깃 저장소가 아닙니다: .git

 저장소 초기화
[sidepower@localhost git_project1]$ git init
/home/sidepower/test/Git/git_project1/.git/ 안의 빈 깃 저장소를 다시 초기화했습니다

현재 상태 확인
[sidepower@localhost git_project1]$ git status
현재 브랜치 master

아직 커밋이 없습니다

추적하지 않는 파일:
  (커밋할 사항에 포함하려면 "git add <파일>..."을 사용하십시오)
    git_start.class
    git_start.java

커밋할 사항을 추가하지 않았지만 추적하지 않는 파일이 있습니다 (추적하려면 "git
add"를 사용하십시오)

 인덱스 등록하기
[sidepower@localhost git_project1]$ git add .

 현재 상태 확인
[sidepower@localhost git_project1]$ git status
현재 브랜치 master

아직 커밋이 없습니다

커밋할 변경 사항:
  (스테이지 해제하려면 "git rm --cached <파일>..."을 사용하십시오)
    새 파일:       git_start.class
    새 파일:       git_start.java

 커밋 하기
[sidepower@localhost git_project1]$ git commit -m "Two Starting git.."
[master (최상위-커밋) e3979ea] Two Starting git..
 2 files changed, 6 insertions(+)
 create mode 100644 git_start.class
 create mode 100644 git_start.java

 현재 상태 확인
[sidepower@localhost git_project1]$ git status
현재 브랜치 master
커밋할 사항 없음, 작업 폴더 깨끗함

 git 로그 확인
[sidepower@localhost git_project1]$ git log
commit e3979ea2e1b00d9986b6b7ea3f79d1fac91fcf08 (HEAD -> master) 
Author: sidepower1 <sidepwer1@git.com>
Date:   Fri Jul 2 02:52:59 2021 -0400

    Two Starting git..

 

 

감사합니다.

반응형

댓글