목차
2. Git의 기초(핵심)
- 저장소를 만들고 설정하는 방법
- 파일을 추적하거나(Track) 추적을 그만두는 방법
- 변경 내용을 Stage 하고 커밋하는 방법
- 파일이나 파일 패턴을 무시하도록 Git을 설정하는 방법
- 실수를 쉽고 빠르게 만회하는 방법
- 프로젝트 히스토리를 조회하고 커밋을 비교하는 방법
- 리모트 저장소에 Push 하고 Pull 하는 방법
2.1 Git 저장소 만들기 : Git 저장소 생성 & 워킹 디렉토리 Checkout
- 기존 디렉토리 사용 : 버전관리 안하던 프로젝트를 Git으로 관리하고 싶은 경우. $ git init
- .git 이라는 하위 디렉토리 생성 하기
- [해당 프로젝트 디렉토리 이동 > $ git init 실행]
- .git 디렉토리 : 저장소에 필요한 뼈대 파일(Skeleton) 보관.
- [해당 프로젝트 디렉토리 이동 > $ git init 실행]
- Git 파일 버전 관리 시작하기
- [$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'] - 저장소에 파일을 추가하고 커밋해야 시작
- git add 명령으로 파일을 추가하고 git commit 명령으로 커밋한다
- [$ git add *.c
- .git 이라는 하위 디렉토리 생성 하기
- 기존 저장소 Clone : git clone <url>
- 동일 이름으로 복사
- $ git clone https://github.com/libgit2/libgit2
- 이름 변경하여 복사
- $ git clone https://github.com/libgit2/libgit2 mylibgit
- 다른 프로젝트에 참여하려거나(Contribute) Git 저장소를 복사하고 싶을 때 git clone 명령 사용
- "checkout" 이 아니라 "clone" 이라는 점
- SVN과 가장 큰 차이점은 서버에 있는 거의 모든 데이터를 복사
- git clone 을 실행하면 프로젝트 히스토리를 전부 받아온다.
- “libgit2” 라는 디렉토리를 만들고 그 안에 .git 디렉토리를 만든다.
- 그리고 저장소의 데이터를 모두 가져와서 자동으로 가장 최신 버전을 Checkout 해 놓는다
- Checkout으로 생성한 파일을 볼 수 있고 당장 하고자 하는 일을 시작할 수 있다.
- 프로토콜 여러가지 사용 가능 : https:// ,git:// , SSH user@server:path/to/repo.git
- 동일 이름으로 복사
2.2 수정하고 저장소에 저장하기
- 파일을 수정하고 파일의 스냅샷을 커밋해 보자.
- 파일을 수정하다가 저장하고 싶으면 스냅샷을 커밋한다.
- 파일의 분류
- Tracked : 스냅샷 포함 되어 있음
- Unmodified : 수정하지 않음
- Modified : 수정함
- Staged : 커밋으로 저장소에 기록 예정(=Git이 알고있는 상태)
- Untracked : 스냅샷 미포함
- 관리 사이클 : check out > Tracked & Unmodified > Filed Changed > Modified > Git Add(Staged) > Git Commit
- Tracked : 스냅샷 포함 되어 있음
- 파일의 상태 확인하기 : $ git status
- On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean- 현재 작업 중인 브랜치를 알려주며, 서버의 같은 브랜치로부터 진행된 작업을 알려준다.
- On branch master
- 파일을 새로 추적하기 : git add
- “Changes to be committed”
- Staged 상태의 파일을 표시한다. add를 수행하면 여기에 표시된다.
- 커밋하면 git add 를 실행한 시점의 파일이 커밋되어 저장소 히스토리에 남는다
- git add 명령은 파일 또는 디렉토리의 경로를 아규먼트로 받는다.
- 디렉토리면 아래에 있는 모든 파일들까지 재귀적으로 추가한다.
- “Changes to be committed”
- Modified 상태의 파일을 Stage 하기 : Tracked 상태인 파일을 수정하는 법
- Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
- 수정한 파일이 Tracked 상태이지만 아직 Staged 상태는 아니다
- 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: CONTRIBUTING.md - git add 명령 사용
- 파일을 새로 추적할 때
- 수정한 파일을 Staged 상태로 만들 때
- Merge 할 때 충돌난 상태의 파일을 Resolve 상태로 만들때도 사용한다.
- add 의미 : 프로젝트에 파일을 추가한다 X : 다음 커밋에 추가한다 O
- Changes to be committed:
- git add 명령을 실행하면 그 시점의 파일을 Staged 상태로 만든다.
- 마지막으로 git add 명령을 실행했을 때의 버전이 커밋된다.
- git add 명령 후 파일을 수정하면 git add 명령을 다시 실행해서 Staged 상태로 만들어야 한다.
- 파일 상태를 짤막하게 확인하기 : short status
- git status -s 또는 git status --short 처럼 옵션을 주면 현재 변경한 상태를 짤막하게 보여준다.
- $ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt - ?? : 아직 추적하지 않는 새 파일
- A: Staged 상태로 추가한 파일 중 새로 생성한 파일
- M : 수정한 파일
- 왼쪽에는 Staging Area에서의 상태를, 오른쪽에는 Working Tree에서의 상태를 표시한다
- 위 예시
- README 파일 : 내용을 변경했지만, Staged 상태 아님
- lib/simplegit.rb 파일 : 내용을 변경하고 Staged 상태 추가 완료
- Rakefile : 변경하고 Staged 상태로 추가 후 또 변경해서 Staged 이면서 Unstaged 상태.
- 파일 무시하기(관리 안하기) : .gitignore 파일을 만들고 그 안에 무시할 파일 패턴을 적는다
- $ cat .gitignore
*.[oa]
*~ - .[oa] : 확장자가 “.o” 나 “.a” 인 파일을 Git이 무시하라
- 빌드 시스템이 만들어내는 오브젝트와 아카이브 파일
- ~ : ~ 로 끝나는 모든 파일을 무시하라
- 대부분의 텍스트 편집기에서 임시파일로 사용하는 파일 이름
- ~ 로 끝나는 파일은 Emacs나 VI 같은 텍스트 편집기가 임시로 만들어내는 파일
- .gitignore 파일은 보통 처음에 만들어 두는 것이 편리
- .gitignore 파일은 아래 규칙이 적용되어 있다.
아무것도 없는 라인이나, `#`로 시작하는 라인은 무시한다.
표준 Glob 패턴을 사용한다. 이는 프로젝트 전체에 적용된다.
슬래시(/)로 시작하면 하위 디렉토리에 적용되지(Recursivity) 않는다.
디렉토리는 슬래시(/)를 끝에 사용하는 것으로 표현한다.
느낌표(!)로 시작하는 패턴의 파일은 무시하지 않는다. - Glob 패턴 : 정규표현식을 단순하게 만든 것으로 생각하면 되고 보통 쉘에서 많이 사용
- 애스터리스크(*)는 문자가 하나도 없거나 하나 이상을 의미
- 애스터리스크 2개를 사용하여 디렉토리 안의 디렉토리 까지 지정할 수 있다.
- a/**/z 패턴은 a/z, a/b/z, a/b/c/z 디렉토리에 사용할 수 있다.
- [abc] : 는 중괄호 안에 있는 문자 중 하나를 의미한다(그러니까 이 경우에는 a, b, c)
- 물음표(?)는 문자 하나
- [0-9] 처럼 중괄호 안의 캐릭터 사이에 하이픈(-)을 사용하면 그 캐릭터 사이에 있는 문자 하나
- 예제 : https://github.com/github/gitignore
- 디렉토리 마다 각각 생성 가능
- $ cat .gitignore
- Staged와 Unstaged 상태의 변경 내용을 보기 : git diff
- 어떤 내용이 변경됐는지 살펴보려면 git status 명령이 아니라 git diff 명령을 사용해야 한다.
- 보통 우리는 '수정했지만, 아직 Staged 파일이 아닌 것?'과 '어떤 파일이 Staged 상태인지?'가 궁금
- 자세하게 볼 때는 git diff 명령을 사용
- 어떤 라인을 추가했고 삭제했는지가 궁금할 때 사용
- 수정했지만 아직 staged 상태가 아닌 파일을 비교해 볼 수 있다.
- 이 명령은 워킹 디렉토리에 있는 것과 Staging Area에 있는 것을 비교한다.
- 수정하고 아직 Stage 하지 않은 것을 보여준다.
- 커밋하려고 Staging Area에 넣은 파일의 변경 부분을 보고 싶으면
- git diff --staged 옵션을 사용
- 저장소에 커밋한 것과 Staging Area에 있는 것을 비교한다.
- git diff 명령은 마지막으로 커밋한 후에 수정한 것들 전부를 보여주지 않는다.
- Unstaged 상태인 것들만 보여준다.
- 수정한 파일을 모두 Staging Area에 넣었다면 git diff 명령은 아무것도 출력하지 않는다.
- Stage 한 후에 다시 수정해도 git diff 명령을 사용할 수 있다.
- 이때는 Staged 상태인 것과 Unstaged 상태인 것을 비교한다.
- git diff 명령으로 Unstaged 상태인 변경 부분을 확인할 수 있다.
- Staged 상태인 파일은 git diff --cached 옵션으로 확인한다.
- --staged 와 --cached 는 같은 옵션이다.
- 변경사항 커밋하기 : git commit
- 수정한 것을 커밋하기 위해 Staging Area에 파일을 정리했다. Unstaged 상태의 파일은 커밋되지 않는다는 것을 기억해야 한다. Git은 생성하거나 수정하고 나서 git add 명령으로 추가하지 않은 파일은 커밋하지 않는다. 그 파일은 여전히 Modified 상태로 남아 있다. 커밋하기 전에 git status 명령으로 모든 것이 Staged 상태인지 확인할 수 있다. 그 후에 git commit 을 실행하여 커밋한다.
- Git status 확인 -> Git Add -> Git commit
- 명령을 실행하면 Git 설정에 지정된 편집기가 실행
- 쉘의 EDITOR 환경 변수에 등록된 편집기
- git config --global core.editor 명령으로 어떤 편집기를 사용할지 설정 가능
- 아래와 같은 내용을 표시한다(아래 예제는 Vim 편집기).
- 커밋 메시지의 첫 라인은 비어 있고 둘째 라인부터 git status 명령의 결과가 채워진다.
- 커밋한 내용을 쉽게 기억할 수 있도록 이 메시지를 포함할 수도 있고 메시지를 전부 지우고 새로 작성할 수 있다
- git commit 에 -v 옵션을 추가하면 편집기에 diff 메시지도 추가(뭘 수정했는지)
- 내용을 저장하고 편집기를 종료하면 Git은 입력된 내용새 커밋을 하나 완성한다.
- 메시지를 인라인으로 첨부할 수도 있다. : git commit -m
- $ git commit -m "Story 182: Fix benchmarks for speed"
[master 463dc4f] Story 182: Fix benchmarks for speed
2 files changed, 2 insertions(+)
create mode 100644 README - 위 예제는 (master) 브랜치에 커밋했고 체크섬은 (463dc4f)이라고 알려준다.
- 수정한 파일이 몇 개이고 삭제됐거나 추가된 라인이 몇 라인인지 알려준다.
- Git은 Staging Area에 속한 스냅샷을 커밋한다는 것을 기억해야 한다.
- 수정은 했지만, 아직 Staging Area에 넣지 않은 것은 다음에 커밋할 수 있다.
- 커밋할 때마다 프로젝트의 스냅샷을 기록하기 때문에 나중에 스냅샷끼리 비교하거나 예전 스냅샷으로 되돌릴 수 있다.
- 수정한 것을 커밋하기 위해 Staging Area에 파일을 정리했다. Unstaged 상태의 파일은 커밋되지 않는다는 것을 기억해야 한다. Git은 생성하거나 수정하고 나서 git add 명령으로 추가하지 않은 파일은 커밋하지 않는다. 그 파일은 여전히 Modified 상태로 남아 있다. 커밋하기 전에 git status 명령으로 모든 것이 Staged 상태인지 확인할 수 있다. 그 후에 git commit 을 실행하여 커밋한다.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Your branch is up-to-date with 'origin/master'.
#
# Changes to be committed:
# new file: README
# modified: CONTRIBUTING.md
#
~
~
~
".git/COMMIT_EDITMSG" 9L, 283C
- Staging Area 생략하기 : $ git commit -a 옵션
- Staging Area는 커밋할 파일을 정리한다는 점에서 매우 유용하지만 복잡하기만 하고 필요하지 않은 때도 있다.
- 아주 쉽게 Staging Area를 생략할 수 있다.
- git commit 명령을 실행할 때 -a 옵션을 추가하면 Tracked 상태의 파일을 자동으로 Staging Area에 넣는다.
- git add 명령을 실행하는 수고를 덜 수 있다.
- 파일 삭제하기
- Git에서 파일을 제거하려면 git rm 명령으로 Tracked 상태의 파일을 삭제한 후에 (정확하게는 Staging Area에서 삭제하는 것) 커밋해야 한다.
- 워킹 디렉토리에 있는 파일도 삭제하기 때문에 실제로 파일도 지워진다.
- 단순히 워킹 디렉터리에서 파일을 삭제하고 git status 명령으로 상태를 확인하면 “Changes not staged for commit” (즉, Unstaged 상태)라고 표시해준다
- $ rm PROJECTS.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: PROJECTS.md
no changes added to commit (use "git add" and/or "git commit -a")
- $ rm PROJECTS.md
- 그리고 git rm 명령을 실행하면 삭제한 파일은 Staged 상태가 된다. 커밋하면 파일은 삭제되고 Git은 이 파일을 더는 추적하지 않는다.
- 이미 파일을 수정했거나 Staging Area에(역주 - Git Index라고도 부른다) 추가했다면 -f 옵션을 주어 강제로 삭제해야 한다.
- 이 점은 실수로 데이터를 삭제하지 못하도록 하는 안전장치다.
- 커밋 하지 않고 수정한 데이터는 Git으로 복구할 수 없기 때문이다.
- Staging Area에서만 제거하고 워킹 디렉토리에 있는 파일은 지우지 않고 남겨둘 수 있다.
- $ git rm --cached README
- 다시 말해서 하드디스크에 있는 파일은 그대로 두고 Git만 추적하지 않게 한다.
- 이것은 .gitignore 파일에 추가하는 것을 빼먹었거나 대용량 로그 파일이나 컴파일된 파일인 .a 파일 같은 것을 실수로 추가했을 때 쓴다.
- --cached 옵션을 사용하여 명령을 실행한다.
- 여러 개의 파일이나 디렉토리를 한꺼번에 삭제할 수도 있다.
- 아래와 같이 git rm 명령에 file-glob 패턴을 사용한다.
$ git rm log/\*.log
* 앞에 \ 을 사용한 것을 기억하자. 파일명 확장 기능은 쉘에만 있는 것이 아니라 Git 자체에도 있기 때문에 필요하다. 이 명령은 log/ 디렉토리에 있는 .log 파일을 모두 삭제한다. 아래의 예제처럼 할 수도 있다.
$ git rm \*~
이 명령은 ~ 로 끝나는 파일을 모두 삭제한다.
- 아래와 같이 git rm 명령에 file-glob 패턴을 사용한다.
- 파일 이름 변경하기 : $ git mv file_from file_to
- Git은 다른 VCS 시스템과는 달리 파일 이름의 변경이나 파일의 이동을 명시적으로 관리하지 않는다.
- 다시 말해서 파일 이름이 변경됐다는 별도의 정보를 저장하지 않는다.
- Git은 똑똑해서 굳이 파일 이름이 변경되었다는 것을 추적하지 않아도 아는 방법이 있다.
- 파일의 이름이 변경된 것을 Git이 어떻게 알아내는지 살펴보자.
- 이렇게 말하고 Git에 mv 명령이 있는 게 좀 이상하겠지만, 아래와 같이 파일 이름을 변경할 수 있다.
- git mv 명령은 아래 명령어를 수행한 것과 완전 똑같다.
- $ mv README.md README
$ git rm README.md
$ git add README - git mv 명령은 일종의 단축 명령어이다.
- 이 명령으로 파일 이름을 바꿔도 되고 mv 명령으로 파일 이름을 직접 바꿔도 된다.
- 단지 git mv 명령은 편리하게 명령을 세 번 실행해주는 것 뿐이다.
- 중요한 것은 이름을 변경하고 나서 꼭 rm/add 명령을 실행해야 한다는 것
- $ mv README.md README
2.3 커밋 히스토리 조회하기 : Git에는 히스토리를 조회하는 명령어인 git log 가 있다.
특별한 아규먼트 없이 git log 명령을 실행하면 저장소의 커밋 히스토리를 시간순으로 보여준다. 즉, 가장 최근의 커밋이 가장 먼저 나온다. 그리고 이어서 각 커밋의 SHA-1 체크섬, 저자 이름, 저자 이메일, 커밋한 날짜, 커밋 메시지를 보여준다.
원하는 히스토리를 검색할 수 있도록 git log 명령은 매우 다양한 옵션을 지원한다. 여기에서는 자주 사용하는 옵션을 설명한다.
여러 옵션 중 -p, --patch 는 굉장히 유용한 옵션이다.
-p, --patch 는 각 커밋의 diff 결과를 보여준다.
`-2`가 있는데 최근 두 개의 결과만 보여주는 옵션이다:
이 옵션은 직접 diff를 실행한 것과 같은 결과를 출력하기 때문에 동료가 무엇을 커밋했는지 리뷰하고 빨리 조회하는데 유용하다.
. --stat 옵션으로 각 커밋의 통계 정보를 조회할 수 있다.
이 결과에서 --stat 옵션은 어떤 파일이 수정됐는지, 얼마나 많은 파일이 변경됐는지, 또 얼마나 많은 라인을 추가하거나 삭제했는지 보여준다. 요약정보는 가장 뒤쪽에 보여준다.
다른 또 유용한 옵션은 --pretty 옵션이다. 이 옵션을 통해 히스토리 내용을 보여줄 때 기본 형식 이외에 여러 가지 중에 하나를 선택할 수 있다. 몇개 선택할 수 있는 옵션의 값이 있다. oneline 옵션은 각 커밋을 한 라인으로 보여준다. 이 옵션은 많은 커밋을 한 번에 조회할 때 유용하다. 추가로 short, full, fuller 옵션도 있는데 이것은 정보를 조금씩 가감해서 보여준다.
가장 재밌는 옵션은 format 옵션이다.
나만의 포맷으로 결과를 출력하고 싶을 때 사용한다. 특히 결과를 다른 프로그램으로 파싱하고자 할 때 유용하다. 이 옵션을 사용하면 포맷을 정확하게 일치시킬 수 있기 때문에 Git을 새 버전으로 바꿔도 결과 포맷이 바뀌지 않는다.
저자(Author) 와 커미터(Committer) 를 구분하는 것
저자는 원래 작업을 수행한 원작자
커밋터는 마지막으로 이 작업을 적용한(저장소에 포함시킨) 사람이다.
만약 당신이 어떤 프로젝트에 패치를 보냈고 그 프로젝트의 담당자가 패치를 적용했다면 두 명의 정보를 모두 알 필요가 있다. 그래서 이 경우 당신이 저자고 그 담당자가 커미터다. 분산 환경에서의 Git 에서 이 주제에 대해 자세히 다룰 것이다.
oneline 옵션과 format 옵션은 --graph 옵션과 함께 사용할 때 더 빛난다.
이 명령은 브랜치와 머지 히스토리를 보여주는 아스키 그래프를 출력한다.
git log 명령의 기본적인 옵션과 출력물의 형식에 관련된 옵션을 살펴보았다.
git log 명령은 앞서 살펴본 것보다 더 많은 옵션을 지원한다.
git log 주요 옵션 는 지금 설명한 것과 함께 유용하게 사용할 수 있는 옵션이다. 각 옵션으로 어떻게 log 명령을 제어할 수 있는지 보여준다.
- 조회 제한조건
출력 형식과 관련된 옵션을 살펴봤지만 git log 명령은 조회 범위를 제한하는 옵션들도 있다. 히스토리 전부가 아니라 부분만 조회한다. 이미 최근 두 개만 조회하는 -2 옵션은 살펴봤다. 실제 사용법은 `-<n>`이고 n은 최근 n개의 커밋을 의미한다. 사실 이 옵션을 자주 쓰진 않는다. Git은 기본적으로 출력을 pager류의 프로그램을 거쳐서 내보내므로 한 번에 한 페이지씩 보여준다.
반면 --since 나 --until 같은
시간을 기준으로 조회하는 옵션은 매우 유용하다. 지난 2주 동안 만들어진 커밋들만 조회하는 명령은 아래와 같다.
$ git log --since=2.weeks
이 옵션은 다양한 형식을 지원한다."2008-01-15" 같이 정확한 날짜도 사용할 수 있고 "2 years 1 day 3 minutes ago" 같이 상대적인 기간을 사용할 수도 있다.
--author 옵션으로 저자를 지정하여 검색할 수도 있고
--grep 옵션으로 커밋 메시지에서 키워드를 검색할 수도 있다
진짜 유용한 옵션으로 -S 가 있는데 이 옵션은 코드에서 추가되거나 제거된 내용 중에 특정 텍스트가 포함되어 있는지를 검색한다. 예를 들어 어떤 함수가 추가되거나 제거된 커밋만을 찾아보려면 아래와 같은 명령을 사용한다.
$ git log -S function_name
마지막으로 파일 경로로 검색하는 옵션이 있는데 이것도 정말 유용하다.
디렉토리나 파일 이름을 사용하여 그 파일이 변경된 log의 결과를 검색할 수 있다. 이 옵션은 -- 와 함께 경로 이름을 사용하는데 명령어 끝 부분에 쓴다(역주 - git log — path1 path2).
git log 조회 범위를 제한하는 옵션 은 조회 범위를 제한하는 옵션들이다.
이제 살펴볼 예제는 Merge 커밋을 제외한 순수한 커밋을 확인해보는 명령이다.
--no-merges 옵션을 사용하면 검색 결과에서 머지 커밋을 표시하지 않도록 할 수 있다.
$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ --before="2008-11-01" --no-merges -- t/
2.4 되돌리기 $ git commit --amend
일을 하다보면 모든 단계에서 어떤 것은 되돌리고(Undo) 싶을 때가 있다. 이번에는 우리가 한 일을 되돌리는 방법을 살펴본다. 한 번 되돌리면 복구할 수 없기에 주의해야 한다. Git을 사용하면 우리가 저지른 실수는 대부분 복구할 수 있지만 되돌린 것은 복구할 수 없다.
종종 완료한 커밋을 수정해야 할 때가 있다. 너무 일찍 커밋했거나 어떤 파일을 빼먹었을 때 그리고 커밋 메시지를 잘못 적었을 때 한다. 다시 커밋하고 싶으면 파일 수정 작업을 하고 Staging Area에 추가한 다음 --amend 옵션을 사용하여 커밋을 재작성 할 수 있다.
이 명령은 Staging Area를 사용하여 커밋한다. 만약 마지막으로 커밋하고 나서 수정한 것이 없다면(커밋하자마자 바로 이 명령을 실행하는 경우) 조금 전에 한 커밋과 모든 것이 같다. 이때는 커밋 메시지만 수정한다.
편집기가 실행되면 이전 커밋 메시지가 자동으로 포함된다. 메시지를 수정하지 않고 그대로 커밋해도 기존의 커밋을 덮어쓴다.
커밋을 했는데 Stage 하는 것을 깜빡하고 빠트린 파일이 있으면 아래와 같이 고칠 수 있다.
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
여기서 실행한 명령어 3개는 모두 커밋 한 개로 기록된다. 두 번째 커밋은 첫 번째 커밋을 덮어쓴다.
이렇게 --amend 옵션으로 커밋을 고치는 작업은, 추가로 작업한 일이 작다고 하더라도 이전의 커밋을 완전히 새로 고쳐서 새 커밋으로 변경하는 것을 의미한다. 이전의 커밋은 일어나지 않은 일이 되는 것이고 당연히 히스토리에도 남지 않는다.
--amend 옵션으로 커밋을 고치는 작업이 주는 장점은 마지막 커밋 작업에서 아주 살짝 뭔가 빠뜨린 것을 넣거나 변경하는 것을 새 커밋으로 분리하지 않고 하나의 커밋에서 처리하는 것이다. “앗차, 빠진 파일 넣었음”, “이전 커밋에서 오타 살짝 고침” 등의 커밋을 만들지 않겠다는 말이다.
- 파일 상태를 Unstage로 변경하기 : $ git reset HEAD <fileName>
다음은 Staging Area와 워킹 디렉토리 사이를 넘나드는 방법을 설명한다. 두 영역의 상태를 확인할 때마다 변경된 상태를 되돌리는 방법을 알려주기 때문에 매우 편리하다.
git reset 명령은 매우 위험하다. --hard 옵션과 함께 사용하면 더욱 위험하다. 하지만 위에서 처럼 옵션 없이 사용하면 워킹 디렉토리의 파일은 건드리지 않는다.
- Modified 파일 되돌리기 : git checkout -- <file>
어떻게 해야 CONTRIBUTING.md 파일을 수정하고 나서 다시 되돌릴 수 있을까? 그러니까 최근 커밋된 버전으로(아니면 처음 Clone 했을 때처럼 워킹 디렉토리에 처음 Checkout 한 그 내용으로) 되돌리는 방법이 무얼까? git status 명령이 친절하게 알려준다. 바로 위에 있는 예제에서 Unstaged 부분을 보자
git checkout — [file] 명령은 꽤 위험한 명령이라는 것을 알아야 한다.
원래 파일로 덮어썼기 때문에 수정한 내용은 전부 사라진다. 수정한 내용이 진짜 마음에 들지 않을 때만 사용하자.
변경한 내용을 쉽게 버릴수는 없고 하지만 당장은 되돌려야만 하는 상황이라면 Stash와 Branch를 사용하자. Git 브랜치 에서 다루는 이 방법들이 훨씬 낫다.
Git으로 커밋 한 모든 것은 언제나 복구할 수 있다. 삭제한 브랜치에 있었던 것도, --amend 옵션으로 다시 커밋한 것도 복구할 수 있다(자세한 것은 데이터 복구 에서 다룬다). 하지만 커밋하지 않고 잃어버린 것은 절대로 되돌릴 수 없다.
2.5 리모트 저장소
리모트 저장소는 인터넷이나 네트워크 어딘가에 있는 저장소를 말한다.
저장소는 여러 개가 있을 수 있는데 어떤 저장소는 읽고 쓰기 모두 할 수 있고 어떤 저장소는 읽기만 가능할 수 있다.
간단히 말해서 다른 사람들과 함께 일한다는 것은 리모트 저장소를 관리하면서 데이터를 거기에 Push 하고 Pull 하는 것이다.
리모트 저장소를 관리한다는 것은 저장소를 추가, 삭제하는 것뿐만 아니라 브랜치를 관리하고 추적할지 말지 등을 관리하는 것을 말한다.
원격 저장소라 하더라도 로컬 시스템에 위치할 수도 있다.
- 리모트 저장소 확인하기 : $ git remote
- git remote 명령으로 "현재 프로젝트에 등록된" 리모트 저장소를 확인할 수 있다.
- 이 명령은 리모트 저장소의 단축 이름을 보여준다.
- 저장소를 Clone 하면 `origin`이라는 리모트 저장소가 자동으로 등록되기 때문에 `origin`이라는 이름을 볼 수 있다.
- -v 옵션을 주어 단축이름과 URL을 함께 볼 수 있다. : $ git remote -v
- origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
- origin https://github.com/schacon/ticgit (fetch)
- 리모트 저장소 추가하기 : $ git remote add pb https://github.com/paulboone/ticgit
- 이전 절에서도 git clone 명령이 묵시적으로 origin 리모트 저장소를 어떻게 추가되는지 설명했었지만 수박 겉핥기식으로 살펴봤을 뿐이었다.
- 기존 워킹 디렉토리에 새 리모트 저장소를 쉽게 추가할 수 있는데 git remote add <단축이름> <url> 명령을 사용한다.
- 리모트 저장소를 Pull 하거나 Fetch 하기 : $ git fetch <remote>
- 앞서 설명했듯이 리모트 저장소에서 데이터를 가져오려면 간단히 아래와 같이 실행한다.
- 이 명령은 로컬에는 없지만, 리모트 저장소에는 있는 데이터를 모두 가져온다. 그러면 리모트 저장소의 모든 브랜치를 로컬에서 접근할 수 있어서 언제든지 Merge를 하거나 내용을 살펴볼 수 있다.
저장소를 Clone 하면 명령은 자동으로 리모트 저장소를 “origin” 이라는 이름으로 추가한다. 그래서 나중에 git fetch origin 명령을 실행하면 Clone 한 이후에(혹은 마지막으로 가져온 이후에) 수정된 것을 모두 가져온다. git fetch 명령은 리모트 저장소의 데이터를 모두 로컬로 가져오지만, 자동으로 Merge 하지 않는다. 그래서 당신이 로컬에서 하던 작업을 정리하고 나서 수동으로 Merge 해야 한다.
그냥 쉽게 git pull 명령으로 리모트 저장소 브랜치에서 데이터를 가져올 뿐만 아니라 자동으로 로컬 브랜치와 Merge 시킬 수 있다(다음 섹션과 Git 브랜치 에서 좀더 자세히 살펴본다). 먼저 git clone 명령은 자동으로 로컬의 master 브랜치가 리모트 저장소의 master 브랜치를 추적하도록 한다(물론 리모트 저장소에 master 브랜치가 있다는 가정에서). 그리고 git pull 명령은 Clone 한 서버에서 데이터를 가져오고 그 데이터를 자동으로 현재 작업하는 코드와 Merge 시킨다.
- 앞서 설명했듯이 리모트 저장소에서 데이터를 가져오려면 간단히 아래와 같이 실행한다.
- 리모트 저장소에 Push 하기 : git push <리모트 저장소 이름> <브랜치 이름> $ git push origin master
- 프로젝트를 공유하고 싶을 때 Upstream 저장소에 Push 할 수 있다. 이 명령은 git push <리모트 저장소 이름> <브랜치 이름>`으로 단순하다. master 브랜치를 `origin 서버에 Push 하려면(다시 말하지만 Clone 하면 보통 자동으로 origin 이름이 생성된다) 아래와 같이 서버에 Push 한다.
- 이 명령은 Clone 한 리모트 저장소에 쓰기 권한이 있고, Clone 하고 난 이후 아무도 Upstream 저장소에 Push 하지 않았을 때만 사용할 수 있다. 다시 말해서 Clone 한 사람이 여러 명 있을 때, 다른 사람이 Push 한 후에 Push 하려고 하면 Push 할 수 없다. 먼저 다른 사람이 작업한 것을 가져와서 Merge 한 후에 Push 할 수 있다. Git 브랜치 에서 서버에 Push 하는 방법에 대해 자세히 설명할 것이다
- 리모트 저장소 살펴보기 : git remote show <리모트 저장소 이름>
- 리모트 저장소의 URL과 추적하는 브랜치를 출력한다. 이 명령은 git pull 명령을 실행할 때 master 브랜치와 Merge 할 브랜치가 무엇인지 보여 준다. git pull 명령은 리모트 저장소 브랜치의 데이터를 모두 가져오고 나서 자동으로 Merge 할 것이다. 그리고 가져온 모든 리모트 저장소 정보도 출력한다.
좀 더 Git을 열심히 사용하다 보면 git remote show 명령으로 더 많은 정보를 보는 날이 온다. 여러분도 언젠가는 아래와 같은 메시지(역주 - 다수의 브랜치를 사용하는 메시지)를 볼 날이 올 것이다.
- 리모트 저장소의 URL과 추적하는 브랜치를 출력한다. 이 명령은 git pull 명령을 실행할 때 master 브랜치와 Merge 할 브랜치가 무엇인지 보여 준다. git pull 명령은 리모트 저장소 브랜치의 데이터를 모두 가져오고 나서 자동으로 Merge 할 것이다. 그리고 가져온 모든 리모트 저장소 정보도 출력한다.
- 리모트 저장소 이름을 바꾸거나 리모트 저장소를 삭제하기 : git remote rename
- 리모트 저장소의 이름을 변경
- pb 를 paul 로 변경하려면 $ git remote rename pb paul
$ git remote
origin
paul
로컬에서 관리하던 리모트 저장소의 브랜치 이름도 바뀐다 - pb/master 로 리모트 저장소 브랜치를 사용했으면 이제는 paul/master 라고 사용해야 한다.
- pb 를 paul 로 변경하려면 $ git remote rename pb paul
- 리모트 저장소를 삭제해야 한다면
- git remote remove 나 git remote rm 명령을 사용한다.
- 서버 정보가 바뀌었을 때, 더는 별도의 미러가 필요하지 않을 때, 더는 기여자가 활동하지 않을 때 필요하다.
$ git remote remove paul
$ git remote
origin
위와 같은 방법으로 리모트 저장소를 삭제하면 해당 리모트 저장소에 관련된 추적 브랜치 정보나 모든 설정 내용도 함께 삭제된다.
- 리모트 저장소의 이름을 변경
2.6 태그
다른 VCS처럼 Git도 태그를 지원한다. 사람들은 보통 릴리즈할 때 사용한다(v1.0, 등등). 이번에는 태그를 조회하고 생성하는 법과 태그의 종류를 설명한다.
- 태그 조회하기
- 태그 붙이기
- Annotated 태그
- Lightweight 태그
- 나중에 태그하기
- 태그 공유하기
- 태그를 Checkout 하기
2.7 Git Alias
Git의 기초를 마치기 전에 Git을 좀 더 쉽고 편안하게 쓸 수 있게 만들어 줄 Alias 라는 팁 알려주려 한다. 우리는 이 책에서 이 팁을 다시 거론하지 않고 이런 팁을 알고 있다고 가정한다. 그래서 알고 있는 것이 좋다.
명령을 완벽하게 입력하지 않으면 Git은 알아듣지 못한다.
Git의 명령을 전부 입력하는 것이 귀찮다면 git config 를 사용하여 각 명령의 Alias을 쉽게 만들 수 있다. 아래는 Alias을 만드는 예이다.
'ToolChain > VCS - git,github' 카테고리의 다른 글
git - 1 시작하기 (0) | 2022.12.11 |
---|---|
Github 적응하기 (0) | 2022.11.27 |