Git 사용법 (1)

Tube·2021년 4월 29일
2

Git

목록 보기
1/2

정의

git은 소스 코드 관리를 위한 분산 버전 관리 시스템이다.

설치

windows

windows_git 해당 사이트 접속 시 자동으로 다운 받아지며 안 받아지면 수동으로 32bit(x86) 64bit(x64)에 맞춰서 다운로드해 주자

Debian or Fedora

패키지 관리 도구를 이용하여 설치한다.
Fedora

$ sudo yum install git

Debian

$ sudo apt-get install git

Mac

Mac은 Mac 패키지 관리자인 homebrew로 설치하는 게 업데이트나 관리 면에서 유용하다.

$ brew install git

버전 업데이트

현재 글을 쓰고 있는 버전은 2.31.1이다.
Ubuntu나 Windows10에는 기본적으로 git이 깔리지만 낮은 버전으로 깔린다. 2.3 버전 이후로 명령어의 변화가 있으니 업데이트해주도록 하자.

$ sudo add-apt-repository ppa:git-core/ppa -y
$ sudo apt-get update
$ sudo apt-get install git -y
$ git --version
2.31.1

최초 설정

git config

git config라는 도구로 설정 내용을 확인하고 변경할 수 있다. Git은 이 설정에 따라 동작한다.
1. /etc/gitconfig: 시스템의 모든 사용자와 모든 저장소에 적용되는 설정이다.
2. ~/.gitconfig, ~/.config/git/config: 해당 사용자에게만 적용되는 설정이다.
3. .git/config: 특정 저장소 내에서만 적용된다.
해당 적용순서는 3 -> 2 -> 1 순서로 우선 적용된다.

사용자 정보 업데이트

사용자 이름과 이메일 주소를 불러와서 적용한다. git은 commit을 할 때마다 이 정보를 사용한다.
한번 commit후에는 변경 불가능하다.

$ git config --global user.name "tube-jeonghoon"
$ git config --global user.email "tube@abc.com"

프로젝트마다 다른 이름과 이메일 주소를 사용하고 싶으면 --global 옵션을 빼준다.

Git 저장소 만들기

새로운 git 저장소 만들기 ( git init )

해당 명령어로 git 저장소를 만들어준다.

$ git init

이 명령은 .git에 대한 하위 디렉터리가 있는 디렉터리인 Git저장소를 만든다. .git디렉터리에는 저장소에 필요한 파일이 들어있다.

기존 git 저장소를 clone 하기 ( git clone )

다른 프로젝트에 참여하거나 이미 만들어진 git 저장소를 복사하고 싶을 때 git clone이라는 명령어를 사용한다
git clone을 사용하면 git history까지 모두 복사해서 온다.

$ git clone https://github.com/tube-jeonghoon/tube-jeonghoon.git

로컬 저장소에 저장하기

워킹 디렉터리의 모든 파일은 크게 TrackedUntracked로 나뉘어진다. Tracked파일은 또 UnmodifiedModifiedStaged로 나뉘어진다.

파일 상태 확인하기 ( git status )

git status명령어를 사용한다.

$ git status
$ git status -s

git status -s 의 -s 옵션은 현재 파일 상태의 간략하게 보여준다.

파일을 추적하기 ( git add )

git add명령어로 git이 파일을 새로 추적할 수 있다.

$ git add README.md

git add (file) 명령어를 통해 디렉터리에 있는 파일을 추적하고 관리하도록한다. git add 명령은 파일 또는 디렉터리의 경로를 argument로 받는다. 디렉터리면 아래에 있는 모든 파일을 추적한다.

Modified 상태의 파일을 Stage 하기 ( git add )

파일 수정 후 git에 추가해보자
첫 번째 유형은

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
	new file:   README.md

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:   TEST.md

$ git add TEST.md
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   README.md
	modified:   TEST.md

보통 Tracked의 파일을 수정하게 되면 "Changes not staged for commit" 상태가 된다. 수정 한 파일이 Tracked상태이지만 아직 Staged상태는 아니라는 것이다. git add명령어로 파일을 다시 추적할 수 있다.

git add는 세 가지 상황에서 쓸 수 있다.
1. 파일을 새로 추적할 때
2. 수정한 파일을 Staged상태로 만들 때
3. Merge할 때 충돌 난 상태의 파일을 Resolve 상태로 만들 때

Staged와 Unstaged 상태의 변경 내용 보기 ( git diff )

어떤 내용이 변경되었는지 확인하려면 git diff명령어를 사용해야 한다.
다음은 Tracked된 파일을 수정해서 StagedUnstaged 상태 모두 가진 상태이다.

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   README.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   README.md

이 상태에서 git commit을 하게 되면 수정되지 않은 README.md가 commit 될 것이다.
무엇이 달라졌는지 확인하자.

$ git diff
diff --git a/README.md b/README.md
index 264dee5..d214cf8 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
 wow!
+wow2
(END)

wow2 라는 구문이 추가된 걸 볼 수 있다. 하지만 git add 다시 staged 상태로 만들지 않으면 wow2라는 구문은 commit 되지 않는다. 수정 한 파일을 모두 git add로 모두 staged 상태로 만들었다면 git diff명령은 아무것도 출력하지 않는다.

Staged 상태 생략하기 ( git commit -a )

git commit에 -a 옵션을 주면 staged 상태가 아니더라도 Tracked 상태면 무조건 commit 한다.

git commit -a -m "force commit"

파일 삭제하기 ( git rm )

git에서 파일을 삭제하려면 git rm명령어로 해당 파일을 삭제한 후 commit 해야 한다. 주의사항은 git rm으로 파일을 삭제하게 되면 실제 데이터도 삭제 되기 때문에 주의해야 한다.

$ git rm untracked.md
rm 'untracked.md'

$ git commit -m "delete untracked.md"
[master 6480c9d] delete untracked.md
 1 file changed, 1 deletion(-)
 delete mode 100644 untracked.md

하지만 데이터를 남기고 git에서만 지울 수도 있다. git rm --cached 명령어를 쓰면 된다.

$ git rm --cached README.md
rm 'README.md'

$ git status
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	README.md

실제 파일은 삭제되어 지질 않았고 Untracked 상태로 바뀌었다.

파일 이름 변경하기 ( git mv )

git에 추가 되어져 있는 파일의 이름을 바꾸고 싶을때는 git mv명령어를 쓰면 된다.

$ git mv README.md README2.md

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    README.md -> README2.md

commit history 조회 하기 ( git log )

git log를 쓰면 commit history를 조회할 수 있다.

$ git log
commit 4fd6359d1c372c969d7f528a421e94a9367e2f65
Author: jeonghoon-tube <shu7081@gmail.com>
Date:   Tue Apr 27 22:12:48 2021 +0900

    v2

commit 761994540c0fd3c831765863c2a77e2b8f57810b
Author: jeonghoon-tube <shu7081@gmail.com>
Date:   Tue Apr 27 22:11:12 2021 +0900

    first commit
(END)

git log 의 대표적인 옵션으로는 -p 옵션과 --stat 옵션이 있다.
-p는 각 커밋의 diff 결과를 보여준다.

$ git log -p -1
commit 9fdea4651f2f7e315ba06fd728bc00222fc61fd3 (HEAD -> master)
Author: jeonghoon-tube <shu7081@gmail.com>
Date:   Tue Apr 27 22:37:35 2021 +0900

    v3

diff --git a/README.md b/README2.md
similarity index 100%
rename from README.md
rename to README2.md
(END)

-1 옵션은 최근 한개의 결과만 보여준다.

--pretty 옵션도 있다.

$ git log --pretty=oneline
9fdea4651f2f7e315ba06fd728bc00222fc61fd3 (HEAD -> master) v3
6480c9dacd0b78704e82366818d33dea8a508af5 delete untracked.md
4fd6359d1c372c969d7f528a421e94a9367e2f65 v2
761994540c0fd3c831765863c2a77e2b8f57810b first commit
(END)

--pretty옵션과 자주 쓰는 format 형식의 옵션도 있다.

$ git log --pretty=format:"%h - %an, %ar : %s"
9fdea46 - jeonghoon-tube, 9 minutes ago : v3
6480c9d - jeonghoon-tube, 32 minutes ago : delete untracked.md
4fd6359 - jeonghoon-tube, 34 minutes ago : v2
7619945 - jeonghoon-tube, 36 minutes ago : first commit
(END)

옵션은 밑에 서술하겠다.

옵션설명
%H커밋 해시
%h짧은 커밋 해시
%T트리 해시
%t짧은 트리 해시
%P부모 해시
%p짧은 부모 해시
%an저자 이름
%ae저자 메일
%ad저자 시각
%ar저자 상대적 시각
%cn커미터 이름
%ce커미터 메일
%cd커미터 시각
%cr커미터 상대적 시각
%s요약

로컬 저장소 되돌리기

git을 되돌릴 때는 크게 두 가지 방법이 있다. reset 명령어와 revert 명령어이다.
큰 차이점은 현재 버전을 커밋으로 남기는지 안 남기는지의 차이가 있다.

현재 커밋을 지운 후 돌아가기 ( git reset )

reset명령어는 현재의 커밋을 남기지 않으면서 이전으로 돌아간다.
예를 들어 로컬저장소에 v1 -> v2 -> v3 이 커밋되어있다. git reset명령어를 쓰면 v1 -> v2 가 된다.

이전 내용으로 강제로 되돌리기 ( git reset --hard )

현재 커밋과 상관없이 강제로 이전 커밋으로 전체를 덮어 써버린다.

$ cat README.md
Hi, my name is version 3

$ git log --oneline
5ee40c3 (HEAD -> master) v3.0
d822cc7 v2.0
68c508b v1.0

$ git reset --hard d822cc7

$ git log --oneline
d822cc7 (HEAD -> master) v2.0
68c508b v1.0

$ cat README.md
Hi, my name is version 2

현재의 작성중인 내용은 살리면서 이전 커밋으로 돌아가기 ( git reset --soft )

현재 커밋된 버전의 내용을 둔 채 커밋만 돌아간다.

$ cat README.md
Hi, my name is version 3

$ git log --oneline
5ee40c3 (HEAD -> master) v3.0
d822cc7 v2.0
68c508b v1.0

$ git reset --soft d822cc7

$ git log --oneline
d822cc7 (HEAD -> master) v2.0
68c508b v1.0

$ cat README.md
Hi, my name is version 3 // 커밋은 돌아갔지만 v3의 내용은 남아있다.

현재 커밋을 버전으로 남긴 후 돌아가기 ( git revert )

revert명령어는 현재의 커밋을 버전으로 남긴 후 새로운 커밋을 만들면서 돌아간다.
예를 들어 로컬저장소에 v1 -> v2 -> v3 이 커밋되어있다. git revert명령어를 쓰면 v1 -> v2 -> v3 -> v2 가 된다.
주의 해야 될 사항은 git reset 과는 다르게 돌아 가고싶은 커밋 번호를 적는게 아니라 취소하고 싶은 커밋을 적어줘야 한다.

$ git log
5ee40c3 (HEAD -> master) v3.0
d822cc7 v2.0
68c508b v1.0

$ git revert 5ee40c3

$ git log --oneline
5c6a014 (HEAD -> master) Revert "v3.0"
449c948 v3.0
b34e0c0 v2.0
7c4556d v1.0

파일 상태를 Untracked로 변경하기 ( git restore --staged )

2개의 파일이 있는데 모르고 git add .명령어로 모두 staged 영역에 넣어버렸다.
둘 중에 하나를 빼야 할 때 어떻게 해야 하는가?

$ git add .
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   text1.md
	new file:   text2.md

"(use "git restore --staged ..." to unstage)" 해당 메시지가 확인된다.
unstaged 영역으로 보내려면 해당 명령어를 입력하라는 뜻이다.

$ git restore --staged text2.md
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   text1.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	text2.md

git 2.23 이전 버전에서는 `git reset HEAD <파일 이름>으로 뺏어야 됐다. 하지만 2.23 이후 버전에서 restore --staged <파일 이름>으로 바뀌였다.

원격 저장소 사용하기

다른 사람들과 함께 일을 하면서 데이터를 원격저장소에 push하고 pull할수 있다.

리모트 저장소 확인하기

git remote명령어로 현재 프로젝트에 등록된 리모트 저장소를 확인할 수 있다.
저장소를 clone 하면 origin이라는 리모트 저장소가 자동으로 등록되기 때문에 origin이라는 이름을 볼 수 있다.

$ git clone https://github.com/tube-jeonghoon/tube-jeonghoon.git
$ cd tube-jeonghoon
$ git remote
origin

리모트 저장소 추가하기 ( git remote add )

새 리모트 저장소는 쉽게 추가할 수 있다. git remote add [단축 이름] [URL]명령어를 쓰면 된다.

$ git remote add tube https://github.com/tube-jeonghoon/git-test.git
$ git remote -v
tube	https://github.com/tube-jeonghoon/git-test.git (fetch)
tube	https://github.com/tube-jeonghoon/git-test.git (push)

이제 원격 저장소에서 로컬 저장소로 데이터를 가져올 때 URL 대신에 단축 이름을 사용할 수 있다.

$ git pull tube
Updating bd1e8dd..347ec38
Fast-forward
 README.md | 1 +
 1 file changed, 1 insertion(+)

원격 저장소에 있는 데이터 가져오기 ( git pull, git fetch )

git pullgit fetch에는 차이점이 있다. git fetch는 원격 저장소에 있는 모든 데이터를 로컬로 가져오지만 자동으로 병합(merge) 하지는 않는다. 로컬에서 하는 작업을 모두 마무리하고 수동으로 병합(merge) 해 줘야 한다. 하지만 git pull은 로컬로 데이터를 가져오면서 자동으로 병합(merge) 한다.

$ git pull tube
Updating bd1e8dd..347ec38
Fast-forward
 README.md | 1 +
 1 file changed, 1 insertion(+)

원격 저장소에 push하기 ( git push )

프로젝트를 원격 저장소에 올리고 싶을 때 git push 명령어를 사용할 수 있다. 사용 방법은 git push [원격 저장소 이름][브랜치 이름]으로 사용하면 된다.

$ git push tube master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 288 bytes | 288.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/tube-jeonghoon/git-test.git
   347ec38..74ddcfe  master -> master

주의 사항으로는 이 방법은 다른 사람이 push 한 뒤에는 push 할 수 없고 원격 저장소에 있는 내용을 가져와(pull) 병합(merge) 한 다음 push 할 수 있다. 자세한 방법은 후술하도록 하겠다.

원격 저장소 살펴보기 ( git remote show )

git remote show [저장소 이름]으로 해당 저장소의 구체적인 정보를 확인할 수 있다.

$ git remote show tube
* remote tube
  Fetch URL: https://github.com/tube-jeonghoon/git-test.git
  Push  URL: https://github.com/tube-jeonghoon/git-test.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

원격 저장소 수정 및 삭제 ( git remote rename )

git remote rename명령어를 사용하면 저장소의 이름을 변경할 수 있다.

$ git remote rename tube wow-tube
$ git remote
origin
wow-tube

git remote rm 명령어로 저장소를 삭제할 수도 있다.

$ git remote rm origin
$ git remote
wow-tube

태그 사용하기 ( git tag )

Git에는 tag를 지원한다. 보통 릴리스할 때 사용한다.

태그 조회하기 ( git tag )

git tag명령어로 현재 있는 태그를 확인 할 수 있다

$ git tag

태그 붙이기

Git 태그에는 Annotated 태그와 Lightweight 태그 두 가지 종류가 있다.

Lightweight 태그

브랜치처럼 가리키는 지점을 최신커밋으로 이동시키지 않는다. 단순히 특정 커밋에 대한 포인터 역활만 한다.

$ git tag v1.4-tube
$ git show v1.4-tube
Annotated 태그

Git 데이터베이스에 태그를 만든 사람의 이름, 이메일과 태그를 만든 날짜, 태그 메시지도 저장하며 -a 옵션과 -m 옵션이 있다. Annotated 태그를 추가할 때 -a를 붙이고 -m으로 태그 메시지도 함께 저장할 수 있다.

$ git tag -a v1.4-tube -m "my version 1.4"
$ git show v1.4

나중에 태그 하기

이전 커밋에 태그를 붙일 때가 발생할 수도 있다. git tag -a [태그 이름][커밋 체크 섬]으로 추가할 수 있다. 커밋 체크 섬 값은 길어서 전부 쓸 수 없다면 일부만 적어줘도 된다.

$ git log --pretty=oneline
74ddcfee4306cdfe416764814597a8a0161f1eab (HEAD -> master, tag: v1.4-tube, tag: v1.4, wow-tube/master) add testfile.md
347ec386a0deb178c8f4af00def1ec7c3a93f30c Update README.md
bd1e8dd285d7f1f0ba3d7948888b8dcf8a682c16 first commit

$ git tag -a v1.3 -m "my version 1.3" 347e
$ git log --pretty=oneline
74ddcfee4306cdfe416764814597a8a0161f1eab (HEAD -> master, tag: v1.4-tube, tag: v1.4, wow-tube/master) add testfile.md
347ec386a0deb178c8f4af00def1ec7c3a93f30c (tag: v1.3) Update README.md
bd1e8dd285d7f1f0ba3d7948888b8dcf8a682c16 first commit

Update README.md 커밋에 tag가 성공적으로 붙었다.

git 단축어 설정 ( git alias )

명령어를 alias에 등록해 간단하게 쓸 수 있다. git config --global명령어를 쓰면 된다. 해당 프로젝트에서만 쓰고 싶음면 --global 옵션은 빼도 무방하다.

$ git config alias.st status
$ git st
On branch master
Your branch is up to date with 'wow-tube/master'.

nothing to commit, working tree clean

몇 가지 자주 등록해 두면 편한 단축키이다.

$ git config alias.last 'log -1 HEAD' // 마지막 커밋 출력
$ git config alias.untracked 'restore --staged'
$ git config --global alias.logl 'log --oneline --decorate --graph --all'

0개의 댓글