Git 시작하기

Git 시작하기

git(이하 깃)이란 컴퓨터 파일의 변경사항을 추적하고 여러 명의 사용자들 간에 해당 파일들의 작업을 조율하기 위한 분산 버전 관리 시스템이다.

git
git

대다수 개발 관련 업체는 형상 관리를 SVN 또는 깃으로 하기 때문에 반드시 숙지할 필요가 있다. 본인은 리눅스에 소스 파일을 내려 받아 설치할 때 말곤 사용해본 적이 없던 것 같아 사용법과 여러 상황을 정리해 보려고 한다.

SVN과의 차이

SVN은 중앙 서버에 다수의 작업자가 Commit을 통하여 작업이 이루어지지만 깃은 작업자 본인의 PC에 로컬 저장소에서 형상 관리를 하고 다른사람에게 공유할 때 Push를 통해 Publish가 된다.

  • 원격 저장소(Remote repository)
    • 여러 사람이 함께 공유하기 위한 공간
    • Github git이랑 같은것인줄, Bitbucket, …
    • 개인 서버에 설정 후 사용
  • 로컬 저장소(Local repository)
    • 작업자 본인 PC에 있는 공간

깃 설치하기

본인에게 맞는 버전을 깃 공식 사이트에서 설치하면 된다. 윈도우의 경우 아래 그림과 같이 버튼을 눌러 Setup 버전으로 설치하면 된다.

git-scm
git-scm

설치 도중 설정할 수 있는 것들이 많은데 본인은 에디터(VS Code 설정) 이외에 아무것도 건들지 않고 계속 Next를 눌러 설치했다. 또한 명령 프롬프트에서 먼저 익힌 후 GUI 클라이언트를 사용할 예정이라 설치 후 환경 변수도 설정했다.

환경변수
환경변수
git 체크
git 체크

초기 설정

본인 이름과 이메일을 먼저 설정해야 하고 해당 정보는 변경 이력에 표시 된다.

# 이름과 이메일을 설정
> git config --global user.name "JongBin Park"
> git config --global user.email jongbin@devbin.kr

# 설정된 config 값 확인
> git config --list
diff.astextplain.textconv=astextplain
http.sslbackend=openssl
http.sslcainfo=C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
core.autocrlf=true
core.fscache=true
core.symlinks=false
pull.rebase=false
credential.helper=manager-core
credential.https://dev.azure.com.usehttppath=true
init.defaultbranch=master
core.editor="C:\Users\jongbin\AppData\Local\Programs\Microsoft VS Code\bin\code" --wait
user.name=JongBin Park
user.email=jongbin@devbin.kr

로컬 저장소 영역

저장소 생성 및 초기화

깃허브의 저장소 네이밍 규칙은 소문자에 하이픈을 쓸 것을 권고하고 있는 것 같다. 아래 그림과 같이 본인은 “git-study”라는 폴더를 생성하고 초기화를 했다.

>git init
Initialized empty Git repository in git-study/.git/
git-study
git-study

SVN에서 체크아웃을 받았을 때 처럼 형상 관리를 위한 디렉토리가 하나 생겼고 tortoiseGit을 사용한다면 디렉토리에 체크표시가 된 것을 확인할 수 있었다.

작업자 본인의 PC에서 본인만 관리하기 때문에 원격 저장소를 사용하지 않는다면 병합 및 충돌과 같은 문제는 일어나지 않는다. 기본적으로 파일 추가 및 커밋 정도가 될 것 같다.

추가 및 커밋

“git-study” 디렉토리 안에 READMD.md 파일을 생성하고 “git status” 명령어를 입력했다.

> git status
On branch master

No commits yet

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

nothing added to commit but untracked files present (use "git add" to track)

해당 파일을 로컬 저장소에 커밋하기 위해 SVN과 마찬가지로 add 후 commit 을 하면 된다.
✓ 만약 잘못 넣은 경우(커밋되기 전) “git reset HEAD” 명령어를 통해 취소할 수 있다.

> git add README.md

> git status
On branch master

No commits yet

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

커밋을 하게 되면 로그를 적는 에디터가 실행되는데 본인은 VS Code 로 설정해두어 아래 그림과 같이 실행되는 것을 볼 수 있다.

commit editor
commit editor

저장 후 닫으면 커밋이 완료됐다는 메세지를 볼 수 있고, log 또한 확인할 수 있다.

[master (root-commit) a0b3669] add "README.md"
 1 file changed, 3 insertions(+)
 create mode 100644 README.md

C:\Users\jongbin\Desktop\git-study>git log
commit a0b3669a5e59e8ab22ddd9ed57bf4f2136f742c8 (HEAD -> master)
Author: JongBin Park <jongbin@devbin.kr>
Date:   Wed Jun 15 12:47:59 2022 +0900

    add "README.md"

되돌리기

커밋한 이력에 대한 되돌리기는 reset 과 revert 명령어가 있다. 각 차이점은 아래와 같다.

명령어 사용법 내용 비고
reset git reset “커밋 hash” 해당하는 커밋 hash(리비전)까지 커밋 이력을 삭제 원격 저장소에 Push한 상황이면 커밋 이력이 맞지 않아 같이 공유한 작업자들의 불편함을 살 수 있음
revert git revert “커밋 hash” 해당하는 커밋 hash에서 수행했던 일을 반대로 수행한 후 커밋 SVN은 되돌릴 리비전을 다른곳에 체크아웃 받아 소스만 수정해서 다시 커밋했었음

파일을 수정하면서 커밋을 한 후 차이점을 직접 확인한다.

> git log --oneline
989de15 (HEAD -> master) 3
4a3415d 2
ffa9a9b 1
a0b3669 add "README.md"

처음 커밋을 제외한 세 번의 커밋을 했으며 먼저 reset을 이용하여 처음 커밋했던 “a0b3669″으로 복원한 후 log 모습이다.

# 해당 커밋 해쉬까지 커밋 내역을 삭제
> git reset a0b3669
Unstaged changes after reset:
M       README.md

> git log --oneline
a0b3669 (HEAD -> master) add "README.md"

코멘트로 남겼던 1, 2, 3인 커밋 내역들이 모두 지워진 것을 확인할 수 있었다.

다시 3번의 커밋을 한 후 log 내역이다. 이번엔 revert를 이용하여 복원을 해본다.

> git log --oneline
c44e2db (HEAD -> master) 3
ce3f641 2
8708d63 1
a0b3669 add "README.md"

> git revert a0b3669
CONFLICT (modify/delete): README.md deleted in (empty tree) and modified in HEAD.  Version HEAD of README.md left in tree.
error: could not revert a0b3669... add "README.md"
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git revert --continue".
hint: You can instead skip this commit with "git revert --skip".
hint: To abort and get back to the state before "git revert",
hint: run "git revert --abort".

오류가 생긴다. revert는 지정한 커밋 hash에서 일어났던 일만 반대로 수행하고 커밋하는 것 같다. 따라서 첫 커밋 때 추가한 README.md 파일을 지우고 커밋하려는데 HEAD에 계속 남아 있어 그런 것 같다. 따라서 처음 커밋한 상황으로 돌아가려면 최근 커밋한 내용부터 순차대로 revert를 해주어야 한다.

> git revert a0b3669..c44e2db

> git log --oneline
f20398c (HEAD) Revert "1"
a247ff5 Revert "2"
74e4769 Revert "3"
c44e2db (master) 3
ce3f641 2
8708d63 1
a0b3669 add "README.md"

파일 관련 되돌리기는 checkout 명령어가 있다. 삭제를 하던, 수정이 됐건 이 명령어로 로컬 저장소에 있는 파일로 되돌릴 수 있다.

>tree /F
폴더 PATH의 목록입니다.
볼륨 일련 번호는 8840-B6EC입니다.
C:.
    README.md


에 하위 폴더가 없습니다.

만약 README.md 파일을 실수로 지웠다면 git ls-files 명령어로 삭제된 파일을 찾아볼 수 있을 것이다. 그리고 checkout 명령어를 통해 삭제된 파일을 로컬 저장소에 있는 파일로 다시 되돌릴 수 있다.

# m 옵션은 수정된 파일을 보여준다
> git ls-files -d
README.md

> git checkout README.md
Updated 1 path from the index

원격 저장소 연결

우선 개인 서버에 bare-repository를 생성한 후 SSH를 통해 동기화가 되는지 먼저 확인한다. 깃허브, 깃랩 등 유명한 저장소를 사용하는 방법은 추 후 포스팅 예정

# 개인 서버에서 bare-repository 생성
❯ mkdir git-study.git
❯ cd git-study.git
❯ git init --bare
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>
Initialized empty Git repository in git/git-study.git/
# 클라이언트에서 방금 만든 저장소 클론
> git clone 개인서버주소/git/git-study.git
Cloning into 'git-study'...
warning: You appear to have cloned an empty repository.

우선 원격 저장소를 만들고 클론까지 잘 되는것을 확인했다.

“git remote add <원격 저장소 별칭> <원격 저장소 주소>” 명령어를 이용하여 로컬 저장소를 원격 저장소에 연결할 수 있으며, “git remote -v” 명령어를 통해 로컬 저장소가 어디에 연결되어 있는지 확인할 수 있다.

> git remote add origin 개인서버주소/git/git-study.git

> git remote -v
origin  개인서버주소/git/git-study.git (fetch)
origin  개인서버주소/git/git-study.git (push)

원격 저장소 영역

로컬 저장소 → 원격 저장소

“git push” 명령어를 통해 저장소의 내용을 원격 저장소에 덮어쓴다. 현재 로그는 아래와 같고 발행까지 진행했다.

> git log --oneline
a0b3669 (HEAD -> master) add "README.md"

> git push origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 399 bytes | 399.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To 개인서버주소/git/git-study.git
 * [new branch]      master -> master

원격 저장소에 발행했으니 다른 작업자도 권한만 있다면 해당 저장소에 있는 내용을 clone 하여 받을 수 있을 것이다.

원격 저장소의 내용 가져오기(최초)

다른 경로에 방금 push 명령으로 올린 것을 가져오려고 한다.

> git clone 개인서버주소/git/git-study.git
Cloning into 'git-study'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.

> git remote -v
origin  개인서버주소/git/git-study.git (fetch)
origin  개인서버주소/git/git-study.git (push)

원격 저장소에 연결된 작업자가 두명이 된 셈이다. 저장소가 공유됨에 따라 발생할 수 있는 여러가지 문제가 있을 것이다.

공유에 따른 문제

같은 커밋 해쉬의 파일을 서로 다르게 수정

편의상 처음 push를 한 작업자는 “작업자 0”, clone을 통해 원격에서 받은 작업자를 “작업자 1″로 놓고 본다면 로그는 아래와 같다.

#작업자 0
> git log --oneline
d5b2acc (HEAD -> master) 작업자 0 수정
a0b3669 (origin/master) add "README.md"

#작업자 1
>git log --oneline
bde0b45 (HEAD -> master) 작업자 1 수정
a0b3669 (origin/master, origin/HEAD) add "README.md"

우선 커밋 해쉬가 다른것을 확인할 수 있었고, 작업자 1부터 push를 해보기로 한다.

> git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 340 bytes | 340.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
To 개인서버주소/git/git-study.git
   a0b3669..bde0b45  master -> master
   
> git log --oneline
bde0b45 (HEAD -> master, origin/master, origin/HEAD) 작업자 1 수정
a0b3669 add "README.md"

별 문제 없이 진행되는 것으로 보인다. 이제 작업자 0이 커밋한 내용을 push 해보도록 하자.

> git push origin master
To 개인서버주소/git/git-study.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to '개인서버주소/git/git-study.git'

거부 및 “fetch first”라는 말이 보인다. 깃 또한 SVN처럼 최신의 상태에서 발행하는 것을 원칙으로 하는 것 같다. 그럼 작업자 0은 fetch 를 통해 어떤 문제가 나타나는지 살펴보자.

>git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 320 bytes | 13.00 KiB/s, done.
From ssh://devbin.kr:/usr/home/jongbin/git/git-study
   a0b3669..bde0b45  master     -> origin/master

fetch는 문제없이 수행된다. fetch는 원격 저장소의 내용을 로컬 저장소로 오로지 정보만 가져온다. 그럼 fetch를 했으니 다시 push를 진행해보자.

> git push origin master
To 개인서버주소/git/git-study.git
 ! [rejected]        master -> master (non-fast-forward)

non-fast-forward 애러는 로컬과 원격간 차이가 있어 발생하는 애러라고 한다. 따라서 fetch 및 merge까지 한 후 push를 해야한다.

> git pull origin master
From 개인서버주소/git/git-study
 * branch            master     -> FETCH_HEAD
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

충돌을 해결해보자. 작업자 0이 “git diff” 명령어를 사용하면 차이점을 보여준다.

>git diff
diff --cc README.md
index f47a317,cce0822..0000000
--- a/README.md
+++ b/README.md
@@@ -2,4 -2,4 +2,8 @@@

  git(이하 깃)이란 컴퓨터 파일의 변경사항을 추적하고 여러 명의 사용자들 간에 해당 파일들의 작업을 조율하기 위한 분산 버
전 관리 시스템이다.

- 최초 push를 통해 원격 저장소에 발행한 작업자
 -clone을 통해 받은 작업자가 수정
++<<<<<<< HEAD
++최초 push를 통해 원격 저장소에 발행한 작업자
++=======
++clone을 통해 받은 작업자가 수정
++>>>>>>> bde0b4540f97eb5d4838035f29e420869e779c4d

작업자 0은 작업자 1이 수정한 내용과 본인이 수정한 모든 내용을 수정한 후 merge 및 원격 저장소 발행

> git log --oneline
90cc6e2 (HEAD -> master) Merge branch 'master' of ssh://devbin.kr:/usr/home/jongbin/git/git-study
d5b2acc 작업자 0 수정
bde0b45 (origin/master) 작업자 1 수정
a0b3669 add "README.md"

> git push
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 12 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 652 bytes | 652.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0), pack-reused 0
To 개인서버주소/git/git-study.git
   bde0b45..90cc6e2  master -> master

문제 없이 발행 됐으며 작업자 1도 해당 내용을 받아볼 수 있다.

%d 블로거가 이것을 좋아합니다: