이 섹션의 다중 페이지 출력 화면임. 여기를 클릭하여 프린트.

이 페이지의 일반 화면으로 돌아가기.

개발 도구

1 - Git

Git

1.1 - Git | Git 개요

Git 란 무엇인가.

기존 버젼 관리 툴과는 대치 되는 형태의 파일 버젼 관리 툴이다.

기존의 버젼 관리 툴은 중앙 집중 방식으로 자신만의 저장소가 없어서 작업 내용을 보관 보완(Update) 하려면 반드시 사내 서버에 접속을 하여야만 하여서 장기 출장, 노트북에서의 작업한 내용에 대해서 별 다른 버젼 부여가 불가능 하였다.

하지만 Git 같은 툴이 나오므로서 자신의 하드에 저장소를 만들고 사내 혹은 프로젝트 전체의 저장소의 자신의 작업 내용을 추가/보완/수정 등이 너무나도 편리하게 수행이 가능하게 되었다.

Git 관련 사이트

1.2 - Git | 기본 명령어

git push

Local commit을 Remote repository에 반영 시킨다.

git checkout

작업 트리의 수정된 파일을 index에 있는 것으로 원복한다.

git checkout [파일]

워킹트리의 수정된 파일을 HEAD에 있는 것으로 원복한다.

git checkout HEAD (파일명:생략가능) 

워킹트리의 수정된 파일의 내용을 FETCH_HEAD에 있는 것으로 원복한다.

git checkout FETCH_HEAD (파일명:생략가능) 

git commit

현재 Index 영역에 있는 변경 내역을 commit 영역에 등록한다.

git commit –m “코멘트”

Index에 등록 안된 변경 내역들도 모두 commit 영역에 등록한다.

git commit –a –m “코멘트”

1.3 - Git | Git 기본

이 Git 기본 튜토리얼에서는 Git의 중요 명령에 대해 간략하게 설명한다. 처음 시작하는 저장소 설정에 대한 섹션에서 버전 관리를 할 프로젝트를 새로 시작하는 경우에 필요한 각종 명령의 설명을 한다. 나머지 섹션에서는 일상적으로 사용하는 Git 명령을 소개한다.

이 튜토리얼을 학습 완료하면 Git 저장소 만들기, 프로젝트 스냅 샷의 안전한 저장, 프로젝트 기록 열람 등을 할 수 있다.

Git 연습 : 기본편

1.3.1 - Git | Git 기본 | git init

git init 명령

git init은 Git 저장소를 새로 만드는 명령이다. 이 명령은 버전 관리를하지 않은 기존 프로젝트를 Git 저장소로 변환하거나 새로운 빈 저장소를 생성하고 초기화하는 경우에 사용한다. 이 명령을 제외한 다른 명령은 거의 모든 초기화 된 저장소 이외에는 적용 할 수 없기 때문에이 명령은 새 프로젝트를 시작할 때 보통 처음 실행하는 명령이다.

git init 명령을 실행하면 저장소에 관련된 모든 메타 데이터를 갖는 .git 하위 디렉토리가 프로젝트의 루트에 생성된다. 이 .git 디렉토리 생성을 제외하고 기존 프로젝트에 아무런 변화가 없다 (SVN과는 달리 Git은 각 하위 디렉토리에 .git 폴더가 생성되지 않는다).

사용법

git init

현재 디렉토리를 Git 저장소로 변환한다. 이 명령을 실행하면 현재 디렉토리에 .git 폴더가 생성되고 프로젝트의 버전 관리를 시작할 수 있다.

git init <directory>

지정한 디렉토리에 빈 Git 저장소를 만든다. 이 명령을 실행하면 .git 하위 디렉토리를 포함된 <directory>라는 이름으로 새 폴더가 생성된다.

git init --bare <directory>

작업 디렉토리를 없는 공간에 Git 저장소를 생성하고 초기화한다. 공유 저장소는 반드시 –bare 플래그를 사용하여 작성해야 한다 (아래의 보충 설명 참조). –bare 플래그를 지정하여 만든 저장소 디렉토리명에 무조건 .git를 추가한다. 예를 들어, my-project라는 이름의 저장소 베어 버전은 my-project.git라는 이름의 폴더에 저장한다.

보충 설명

SVN과 비교하면 git init는 새 버전 관리 프로젝트를 만들기위한 매우 간편한 방법을 제공하는 명령이다. Git은 수동으로 저장소 폴더 만들기, 파일 임포트, 작업 복사인 체크 아웃 등은 하지 않아도 된다. 프로젝트 폴더에 git init을 실행하기 만하면 완전한 기능을 가진 Git 저장소를 만들 수 있다.

다만, 대부분의 프로젝트에서 git init 명령은 중앙 저장소를 만들 때 한 번만 사용될 것이며, 각각의 개발자가 로컬 저장소 (중앙 저장소의 작업 복사본)을 만들 때 git init을 사용하지는 않는다. 개발자는 일반적으로 git clone 명령을 사용하여 기존 저장소의 복사본을 로컬 머신에 만든다.

베어 저장소(bare repository)

–bare 플래그를 지정하면 작업 디렉토리가 없는 저장소가 생성되고 그 저장소에서 파일을 편집하거나 변경을 적용 할 수 없다. 베어 저장소가 아닌 경우에 브랜치 푸시하면, 변경 사항이 잘못 기록을 될 수 있기에 중앙 저장소는 반듯이 베어 저장소로 만들어야 한다. –bare의 지정은 그 저장소를 개발 환경으로 서가 아닌 저장용 공간으로 인식시키는 방법이라고 생각하면 된다. 즉, 실질적으로 모든 Git 작업 플로우에서 중앙 저장소는 베어 저장소이며, 개발자의 로컬 저장소는 베어 저장소가 아니다.

Git 튜토리얼 : 베어 저장소

사용 예

중앙 저장소의 작업 복사본을 만들려면 git clone 명령이 더 편리하기 때문에 git init 명령어의 일반적인 사용 사례는 최초 중앙 저장소에 저장고를 만들때만 주로 사용한다 :

ssh @
cd path / above / repo
git init --bare my-project.git

먼저 SSH 통신을 통해 중앙 저장소를 만들려는 서버에 로그인한다.
다음 프로젝트를 저장할 디렉토리로 이동한다.
마지막으로, –bare 플래그를 지정하여 중앙 저장소를 만든다.
그럼, 개발자는 clone my-project.git 명령을 사용하여 자신의 개발 장비에 작업 복사본을 만든다.

1.3.2 - Git | Git 기본 | git clone

git clone 명령

git clone은 기존의 Git 저장소의 복사본을 만드는 명령이다. 이 명령은 svn checkout과 유사하지만, 작업 사본이 자체적으로 완전한 Git 저장소를 구성하는 점이 다르고, 수정된 기록을 자체적으로 가지고 자신의 파일을 관리하고 원래 저장소와는 완전히 독립적인 환경을 제공한다.

이용자의 편의를 위해 clone를 하는 것은 원래의 저장소를 가리키는 origin이라는 이름으로 원격 연결이 자동으로 만들어진다. 이렇게 하면 매우 쉽게 중앙 저장소와 통신을 할 수 있다.

사용법

git clone <repo>

<repo>에 있는 저장소를 로컬 머신에 복제하는 명령이다. <repo>의 저장소는 같은 로컬 머신에 존재해도 되고, HTTP 혹은 SSH를 사용하여 액세스하는 원격 머신에 존재해도 상관 없습니다.

git clone <repo> <directory>

<repo>에 있는 저장소를 로컬 머신에 <directory>라는 이름의 폴더에 복제하는 명령이다.

보충 설명

중앙 저장소가 이미 작성되어 있는 경우는 git clone이 개발자의 작업 복사본을 만드는 가장 일반적인 명령이다. git init 명령뿐만 아니라 복제도 보통 일회성 작업으로 개발자가 일단 작업 복사본 (로컬 저장소)를 생성 한 후 로컬 저장소를 통해 모든 버전 관리 및 협업을 수행한다.

저장소 간 협업

Git에서 “작업 복사본"이 SVN 저장소에서 코드를 체크 아웃하여 얻어지는 작업 복사본과는 크게 다른 개념임을 이해해야 한다. SVN과는 달리 Git은 작업 복사본과 중앙 저장소 사이에 실질적인 차이가 있는 것이 아니라 양자 모두 완벽한 Git 저장소이다.

이를 통해 Git 협업 및 SVN 협업은 기본적으로 다른 것이다. SVN은 중앙 저장소와 작업 복사본 사이의 관계가 중요한 역할을 가지고 있지만, Git의 협력 모델은 저장소 간의 상호 작용적인 내용이다. SVN은 작업 사본을 중앙 저장소에 체크인하는 반면 Git은 하나의 저장소에서 다른 저장소에 커밋(commit)의 푸시(pugh) 또는 풀(pull)을 한다.

Git 튜토리얼 : 저장소 간의 협업

당연한 일이지만, 가지고 있는 Git 저장소에 특별한 의미를 부여 할 수 있다. 예를 들어, Git 저장소를 “중앙” 저장소를 지정하여 Git에서도 ‘중앙 집중식 워크 플로우’를 따라 할 수 있다. 중요한 것은 그것이 버전 관리 시스템 (VCS)와 물리적 연결 상태에서 구별하는 것이 아니라 Git은 단순한 약속으로 결정된다는 것이다.

사용 예

다음 예는 주소가 example.com에서 사용하는 SSH 사용자 이름이 john인 경우, 서버에 저장된 중앙 저장소의 작업 복사본을 만드는 방법을 보여준다 :

git clone ssh://john@example.com/path/to/my-project.git
cd my-project
# Start working on the project

첫 번째 행은 새 Git 저장소를 로컬 머신에서 my-project 폴더에 생성하고 그것을 초기화하고 그것을 중앙 저장소의 파일을 받아오는 명령이다.
이것이 완료되면 현재 디렉토리를 프로젝트로 이동하여 편집, 스냅 샷 커밋, 다른 저장소와 통신 등의 작업을 시작하게 된다.
또한, 복제된 저장소는 .git 확장자가 추가되지 않는다. 이것은 로컬 복사본이 베어 저장소가 아닌 상태에 있다는 것을 의미한다.

1.3.3 - Git | Git 기본 | git config

git config 명령

git config는 설치한 Git (또는 각각의 저장소)에 대해 커멘드 라인 인터페이스(CLI:command line)으로 설정을 변경하는 명령이다. 이 명령을 사용하면 사용자 정보에서 저장소 동작의 초기 설정에 이르기까지 모든 항목의 설정이 가능하다. 일반적으로 사용되는 설정 옵션의 일부는 다음과 같다.

사용법

git config user.name <name>

현재 저장소에서 모든 커밋에 사용되는 저자(author) 이름을 설정한다. 이 명령은 보통 –global 플래그를 지정하여 현재 사용자에 대한 저자 이름 설정을 한다.

git config --global user.name <name>

현재 사용자가 모든 커밋의 저자 이름을 설정한다.

git config --global user.email <email>

현재 사용자가 모든 커밋에 대해 그 저자 이메일 주소를 설정한다.

git config --global alias <alias-name> <git-command>

Git 명령의 alias 명령어를 만든다. 이는 리눅스 alias와 동일한다.

git config --global color.ui "auto"

Git 명령에 사용자 인터페이스에 색 넣도록 설정한다.

git config --system core.editor <editor>

현재 사용중인 머신에서 git commit과 같은 명령을 실행하는 데 사용하는 편집기를 지정한다. 인수 <editor>는 해당 편집기를 기동하는 명령이다 (예를 들어, vi 편집기 등).

git config --global --list

Git 명령에 현재 설정된 정보 조회한다.

git config --global --edit

글로벌 설정 파일을 텍스트 편집기에서 열기 명령으로 이를 사용하여 수동으로 설정 파일을 편집 할 수 있다.

보충 설명

모든 옵션 설정은 일반 텍스트 파일에 저장되기 때문에, git config는 편의성을 높이기 위한 커멘드 라인 인터페이스에 지나지 않는다. 일반적으로 설치 한 Git 설정이 필요한 것은 새로운 개발 머신에서 처음 시작 할 때 뿐이며, 또한 실질적으로 거의 모든 경우에 –global 플래그를 지정한다.

Git의 옵션 설정은 3개의 파일로 나누어 저장되고 다음 명령을 사용하여 개별 저장소 사용자 시스템 전체의 설정 내용을 각각 확인할 수 있다 :

  • <repo>/. git/config : 각 저장소 관련 설정.
  • ~/.gitconfig : 사용자 별 설정. 여기에는 –global 플래그를 지정한 옵션 설정이 저장되어 있다.
  • $(prefix)/etc/gitconfig : 시스템 전체에 대한 설정.

이러한 파일의 옵션 설정이 일치하지 않는 경우, 사용자 별 설정이 시스템 전체에 관한 설정보다 우선순의가 높고 각 저장소 관련 설정이 사용자 별 설정보다 우선순위가 높다.

설정의 우선순위 : 각 저장소 관련 설정 > 사용자 별 설정 > 시스템 전체에 대한 설정

설명 파일을 열면 다음과 같은 내용이 나타난다 :

[user]
name = John Smith
email = john@example.com
[alias]
st = status
co = checkout
br = branch
up = rebase
ci = commit
[core]
editor = vim

이 값은 수동으로 편집 할 수 있으며, 그것은 git config 명령과 똑같은 기능을 한다.

사용 예

Git 설치 후 처음으로 해야 할 일은 사용자의 이름과 이메일 주소를 설정하고, 몇 가지 기본 설정을 사용자 가 정의 할 수 있다. 초기 설정 명령은 일반적으로 다음과 같다.

# Tell Git who you are
git config --global user.name "John Smith"
git config --global user.email john@example.com
# Select your favorite text editor
git config --global core.editor vim
# Add some SVN-like aliases
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.up rebase
git config --global alias.ci commit

이렇게 하면 상기의 ~/.gitconfig 파일이 생성된다.

1.3.4 - Git | Git 기본 | git add

git add 명령

git add 는 작업 디렉토리의 변경을 스테이지(stage) 영역에 추가하는 명령이다. 이 명령은 각각의 파일의 업데이트 내용을 다음 커밋(commit)의 대상으로 추가하는 것을 Git에 지시한다. 그러나 git add 명령만으로는 실제로 로컬 저장소에 아무런 영향을 주지 않고 git commit 명령을 실행하기 전까지는 변경이 실제로 기록되는 것은 아니다.

이러한 명령과 관련하여 작업 디렉토리 및 스테이지(stage) 영역의 상태를 확인하기 위해 git status 명령이 사용된다.

사용법

git add <file>

<file> 에 가해진 모든 변경을 스테이지징(스테이지징 영역에 추가)하고 다음 커밋 대상으로 한다.

git add <directory>

<directory> 의 모든 변경을 스테이지징(스테이지징 영역에 추가)하고 다음 커밋 대상으로 한다.

git add -p

상호작용(interactive) 스테이지(stage) 세션을 시작합니다. 상호작용 스테이지 세션에서는 파일의 일부를 선택하여 스테이지하고 다음 커밋의 대상이 될 수 있다. 이 명령을 실행하면 변경 사항이 표시되고 그에 대한 다음의 명령 입력을 요구한다. y 를 입력하면 그 부분이 스테이지되고 n 을 입력하면 그 부분은 무시되고 s 를 입력하면 그 부분은 더 작은 조각으로 분할되어 e 를 입력하면 그 부분을 수동으로 편집 할 수 있게 , q 를 입력하면 대화 형 세션을 종료한한다.

보충 설명

git add 와 git commit 은 Git의 기본적인 워크 플로우를 구성한다. 모든 Git 사용자는 소속 팀의 협업 모델이 어떻든 이러한 두 명령을 이해해 두지 않으면 안된다. 이 프로젝트의 버전 저장소의 이력을 기록하는 방법이다.

프로젝트의 진행과 함께 편집 / 스테이지 / 커밋의 기본 패턴이 반복된다.
사용자는 먼저 작업 디렉토리에있는 파일을 편집한다.
현재 작업 디렉토리의 상태를 저장하고자 할 때 git add 명령을 사용하여 변경을 스테이지 한다.
스테이지 된 스냅 샷에 문제가 없으면 git commit 명령을 사용하여 그것을 로컬 저장소에 커밋한다.

Git 튜토리얼 : git add Snapshot

git add 명령 및 파일 저장소에 추가를 실행하는 svn add 명령을 혼동해서는 안된다. git add 는 변경에 대해 더 추상적인 수준에서 작동하는 명령이다. 즉, svn add 는 각각의 파일마다 한 번만 호출 명령하지만 git add 는 파일을 수정할 때마다 호출해야 한다. 이것은 장황하게 들릴 수도 있지만, 이 흐름에 따라 프로젝트를 잘 관리 된 상태로 유지하는 것이 용이하다.

스테이징 영역

스테이징 영역은 Git이 가진 독특한 기능 중 하나이며, SVN (또는 Mercurial)에 익숙한 사람들에게는 이해하기 어려운 개념지도 모른다. 이것은 작업 디렉토리와 로컬 저장소 사이의 버퍼라고 생각하면 좋을 것이다.

스테이지를 사용하여 마지막으로 커밋하고 나서 이후의 모든 변경 사항을 한 번에 커밋하는 것이 아니라 관련성이 강한 변경만을 구분하여 초점이 명확한 스냅 샷을 생성하고 실제 커밋을 수행 할 수 있다. 즉, 관련성은 신경 쓰지 않고 원하는대로 파일을 수정 한 후 관련성이 강한 변경을 정리해 스테이지 외에도 조금씩 커밋을 수행함으로써 논리적으로 잘 정리 된 커밋 할 수있는 것이다. 다른 버전 관리 시스템에서도 마찬가지이지만, 프로젝트의 다른 부분에 미치는 영향을 최소화하면서 버그의 원인 추적 및 취소를 쉽게 할 수 있도록 한 번의 커밋은 작은 규모로하는 것이 중요하다.

사용 예

새 프로젝트를 시작할 때 git add 명령은 svn import 명령과 동일한 기능을 한다. 현재 디렉토리의 커밋을 처음 할 경우는 다음의 두 명령을 사용한다 :

git add .
git commit

프로젝트가 순조롭게 진행 시작한 후에는 git add 경로를 입력하여 새 파일을 추가 할 수 있다 :

git add hello.py
git commit

위의 두 명령은 기존 파일에 변경 내용을 기록 할 때 사용한다. 즉, Git은 새 파일을 생성한데 따른 변경 이미 저장소에 저장되어 있는 파일의 내용의 변경을 구분하지 않는다.

1.3.5 - Git | Git 기본 | git commit

git commit 명령

git commit 스태이지(stage) 된 스냅 샷을 로컬 저장소에 커밋하는 명령이다. 커밋 된 스냅 샷은 프로젝트의 “안전하게 보관 된"버전으로 해석 할 수 있고, 명시적으로 변경 지시를 하지 않는 한 Git이 그것을 변경할 수 없다. 이것은 git add 함께 Git의 가장 중요한 종류의 명령이다.

이름은 동일하지만 이 명령은 svn commit 명령과는 전혀 다른 것이다. 스냅 샷은 로컬 저장소에 커밋되기 때문에 다른 Git 저장소에 전혀 영향을주지 않는다.

사용법

git commit

스테이지 된 스냅 샷을 커밋 명령이다. 이 명령을 실행하면 텍스트 편집기가 시작되고 커밋 메시지를 입력해야한다. 메시지를 입력 한 후 파일을 저장하고 편집기를 종료하면 커밋이 수행된다.

git commit -m "<message>"

텍스트 편집기를 시작하지 않고 <message> 를 커밋 메시지로 스테이지 된 스냅 샷을 커밋한다.

git commit -a

작업 디렉토리의 모든 변경 사항의 스냅 샷을 커밋한다. 여기에는 추적 대상 파일 (과거에 git add 명령은 staging 영역에 추가 된 적이 있는 파일)의 수정만 포함된다.

보충 설명

스냅 샷은 항상 로컬 저장소에 커밋된다. 이것은 작업 사본을 중앙 저장소에 커밋 SVN의 기본적인 차이점이다. Git은 필요가 발생하기 전에 중앙 저장소와 통신을 강제하는 것은 아니다. 그냥 준비 영역이 작업 디렉토리와 로컬 저장소 간의 버퍼가있는 것처럼 개발자 개별 로컬 저장소가 작업 성과와 중앙 저장소 사이의 버퍼 역할을 한다.

이것은 Git 사용자 개발 기본 모델에 큰 변화를 일으킨다. Git를 사용하는 개발자는 변경을 직접 중앙 저장소에 커밋하는 것이 아니라 로컬 저장소에 커밋을 축적 할 수 있다. 여기에는 기능을 작은 노력으로 나눌 수 관련성이 강한 커밋을 그룹화 한 채로 유지 가능한 중앙 저장소에 게시하기 전에 로컬 저장소의 구성이 가능 등 SVN 형 협력과 비교하여 많은 장점이 있다. 따라서 개발자는 독립적인 환경에서 작업 할 수 있으며 작업이 적절한 구분을 맞이할 때까지 다른 사람과의 통합을 지연시킬 수 있다.

차이가 아닌 스냅 샷을 저장

SVN과 Git의 사이에는 실질적인 차이가 있지만, 이외에 기본 구조는 완전히 다른 설계 사상에 근거하고 있다. SVN에서 파일의 차이 를 추적하는 반면 Git 버전 관리 모델은 스냅 샷 을 기반으로 한다. 예를 들어, SVN 커밋은 저장소에있는 원본 파일과의 차이점으로 구성된다. 반면 Git은 각 명령마다 각각의 파일의 모든 내용을 기록한다.

Git 튜토리얼 : 변경 내용 아닌 스냅 샷을 저장

이렇게 하면 특정 버전의 파일을 재현 할 때 변경 데이터에서 “조립"필요가 없고, 각 파일의 모든 버전이 Git의 내부 데이터베이스에서 즉시 얻을 수 있기 때문에 Git에서 대부분의 작업은 SVN에 비해 훨씬 빠르게 작동한다.

Git에서 사용되는 스냅 샷 모델은 지점 도구 및 병합 도구에서 협업 워크 플로우에 이르기까지 그 버전 관리 모델의 모든 측면에 광범위한 영향을 미치고 있다.

사용 예

다음의 예에서는 hello.py 라는 이름의 파일 내용을 편집하고 그것을 로컬 저장소에 커밋 할 준비가 되어 있다고 가정한다. 먼저 git add 명령을 사용하여 파일을 스테이지 한 다음 스테이지 된 스냅 샷을 커밋한다.

git add hello.py
git commit

이 명령을 실행하면 텍스트 편집기(git config 명령을 사용하여 임의의 편집기를 지정할 수 있다)가 시작되고 커밋되는 내용의 목록을 표시 함과 동시에 커밋 메시지 입력해야 한다 :

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: hello.py
#

Git은 커밋 메시지의 형식에 관해서 제약은 없지만, 1 행에 커밋 전체 설명을 50 자 이내로 작성하고 두 번째 줄은 빈 줄로 세 번째 줄 이후 변경 사항에 대해 자세히 설명하는 이 표준 형식이다. 다음은 그 예제이다 :

Change the message displayed by hello.py

- Update the sayHello() function to output the user's name
- Change the sayGoodbye() function to a friendlier message

또한 많은 개발자는 커밋 메시지를 현재형으로 기술하는 경향이 있다는 점에 유의해야 한다. 이것은 각 저장소에 대한 작업처럼 읽을 수 있기 때문에 역사를 다시 쓰는 작업을 보다 직관적으로 이해할 수있는 효과가 있다.

1.3.6 - Git | Git 기본 | git status

git status 명령

git status 는 작업 디렉토리의 상태와 스테이지 된 스냅 샷의 상태를 표시하는 명령이다. 이 명령을 실행하면 스테이지 된 변경 내용, 스테이지가 되지 않은 변경 내용, Git에 의한 추적 대상에서 제외 된 파일이 표시된다. 이 상태 정보 출력에는 커밋 된 변경 내역에 대한 정보는 포함되지 않는다 . 커밋 된 변경 내역에 대한 정보를 조회해야 하는 경우는 git log 명령을 사용한다.

사용법

git status

스테이지 파일, 스테이지되지 않은 파일, 추적되지 않는 파일을 나열한다.

보충 설명

git status 는 비교적 간단한 명령이다. 이 명령은 git add 와 git commit 의 두 명령을 실행 한 결과를 확인하는 것 뿐이다. 이 상태 정보는 스테이지 된 파일과 스테이지 되지 않은 파일 관련 정보도 표시된다. 아래의 출력 정보 샘플에서는 git status 를 실행했을 때의 세 가지 주요 카테고리가 표시되어 있다 :

# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: hello.py
#
# Changes not staged for commit:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: main.py
#
# Untracked files:
# (use "git add ..." to include in what will be committed)
#
# hello.pyc

표시 대상에서 파일 제외 .gitignore

추적되지 않는 파일에는 일반적으로 두 종류가 있다. 하나는 프로젝트에 추가 된 직후로 아직 한번도 스테이지 된 적이 없는 파일이고, 다른 하나는 .pyc , .obj , .exe 등의 확장자를 가지는 컴파일 된 바이너리 파일이다. 전자에 대해서는 git status 명령의 출력에 포함 할 유용하지만, 후자는 작업 디렉토리의 인식에 방해가 될 수 있다.

이 때문에 Git은 .gitignore 라는 특수 파일 경로를 작성하여 파일을 표시 대상에서 제외하는 것이 가능하다. 제외 할 파일은 한 줄에 하나씩 기입해야 하며, 또한 와일드 카드로 * 기호를 사용할 수 있다. 예를 들어, 다음 줄을 프로젝트의 루트에있는 .gitignore 파일에 추가하여 컴파일 된 Python 모듈을 git status 표시 대상에서 제외한다 :

*.pyc

사용 예

변경 내용을 커밋하기 전에 저장소의 상태를 확인하는 것은 의도하지 않은 커밋의 실행을 방지하기 위한 좋은 습관이다. 이 예제에서는 스냅 샷의 무대 안팎으로 커밋 전후 저장소의 상태를 표시한다 :

# Edit hello.py
git status
# hello.py is listed under "Changes not staged for commit"
git add hello.py
git status
# hello.py is listed under "Changes to be committed"
git commit
git status
# nothing to commit (working directory clean)

첫 번째 상태 출력은 파일이 스테이지 되지 않은 파일이 표시되어 있다. git add 를 실행 한 결과가 두 번째 git status 에 반영되어 있으며, 마지막 상태 출력은 커밋 할 파일은 아무것도 남아 있지 않은 것이다. 즉, 작업 디렉토리의 상태는 직전의 커밋 결과와 일치되어 표시되어 있다. Git 명령에는 변경의 잘못 쓰기를 방지하기 위해 작업 디렉토리가 클린한 상태 아니면, 사용할 수 없는 것이 있다 (예를 들어, git merge ).

1.3.7 - Git | Git 기본 | git diff

git diff

마지막 git commit과 현재 작업 트리에서 git add하지 않은 파일 간의 차이를 표시한다.

git diff

마지막 git commit과 현재 작업 트리에서 git add 한 파일 간의 차이를 표시한다.

git diff --cached

마지막 git commit과 현재 작업 트리에서 git add 한 파일과하지 않은 파일 두 차분을 동시에 표시한다.

git diff HEAD

1.3.8 - Git | Git 기본 | git log

git log 명령어

git log 는 커밋 된 스냅 샷을 표시하는 명령이다. 이 명령을 사용하여 커밋 된 변경 내용 목록에 대한 필터링 특정 변경 사항 검색을 할 수 있다. git status 명령은 작업 디렉토리와 스테이징 영역의 상태를 확인하기 위한 것 인에 반면, git log 명령은 커밋 된 기록 (커밋 내역)만이 대상이다.

Git 튜토리얼 : git status와 git log

로그 출력은 단순히 커밋 히스토리를 필터링 만보기에서 완전히 사용자 정의 형식으로 표시까지 다양하게 정의 할 수 있다. git log 명령에서 잘 행해지고 있는 설정 예를 아래에 소개한다.

사용법

git log

커밋 히스토리 전체를 기본 형식으로 표시한다. 출력 표시가 2 페이지 이상에 걸치는 경우는 Space 키에서 스크롤이 가능한다. 종료하려면 q 를 입력한다.

git log -n <limit>

보기 커밋 수를 <limit> 제한한다. 예를 들어 git log -n 3 하면 표시 커밋 수는 3이다.

git log --oneline

각 커밋의 내용을 한 줄로 압축하여 표시하는 명령이다. 이 명령은 커밋 히스토리를 간단히 살펴볼 경우에 적합한다.

git log --stat

일반 git log 정보 이외에 수정 된 파일과 그 속에서의 추가 행, 삭제 행 수를 증감 단위로 표시한다.

git log -p

각 커밋에 대한 패치를 표시힌다. 이 명령을 실행하면 커밋 히스토리에서 얻을 수있는 가장 자세한 정보 인 각 커밋의 완전 차등 정보가 표시된다.

git log --author="<pattern>"

특정 저자가 작성한 커밋을 검색한다. 인수 <pattern> 에 일반 텍스트 또는 정규 표현식을 사용할 수 있다.

git log --grep="<pattern>"

커밋 메시지가 <pattern> (일반 텍스트 또는 정규 표현식)과 일치하는 커밋을 검색한다.

git log <since>..<until>

<since> 와 <until> 사이에 있는 커밋만 표시합니다. 2 개의 인수는 커밋 ID 지점 이름, HEAD 는 다른 모든 버전 레퍼런스 를 사용할 수 있다.

git log <file>

지정된 파일을 포함 커밋만 표시한다. 이 명령은 특정 파일의 기록을 조사 목적에 유용하다.

git log --graph --decorate --oneline 

여기에는 몇 가지 유용한 옵션을 제공한다. –graph 플래그를 지정하면 커밋 메시지의 왼쪽에 텍스트 기반의 커밋 히스토리를 그래프 화 한 것이 그린다. –decorate 플래그를 지정하면 표시되는 커밋의 브랜치와 태그 이름을 추가하여 표시한다. –oneline 플래그를 지정하면 커밋 정보를 압축하여 한 줄에 표시하기 위해 최선을 다하고 역사 개관에 유용하다.

보충 설명

git log 명령은 Git에서 커밋 이력을 조회하기 위한 기본 도구이다. 이 명령을 사용하면 프로젝트의 특정 버전을 찾거나 기능 가지를 병합하면 무엇이 바뀌는지 이해하거나 심지어 태만 한 개발자를 발견하는 것조차 할 수 있다.

commit 3157ee3718e180a9476bf2e5cab8e3f1e78a73b7
Author: John Smith

대부분의 정보는 직관적으로 이해할 수 있지만 첫 번째 줄에는 설명이 필요하다. commit 에 이어 40 문자로 이루어진 문자열은 커밋 내용의 SHA-1 체크섬이다. 여기에는 두 가지 목적이 있다.
첫째는 커밋의 무결성을 보장하는 커밋에 손상이 있으면 다른 체크섬이 생성된다.
둘째는 커밋에 대한 고유 ID의 역할을 한다.

이 ID는 git log <since> .. <until> 과 같이 명령에 사용할 수 있으며 특정 커밋을 지정 할 수 있다. 예를 들어 git log 3157e..5ab91 을 실행하면 3157e 와 5ab91 사이 ID를 사용하는 모든 커밋을 표시한다. 체크섬 외에 개인의 커밋을 지정하는 일반적인 방법으로 브랜치 (Git 브랜치 참조) 및 키워드 HEAD를 사용할 수 있다. HEAD 는 브랜치에도 특정 커밋에도 항상 현재의 커밋을 가리킨다.

문자 ~는 부모 커밋에 대한 상대 가르킬 할 경우에 사용한다. 예를 들어, 3157e~1 은 3157e 의 하나 전 부모 커밋을 가르키는 것이고, HEAD ~ 3 은 현재 커밋에서 3개 전의 커밋을 의미한다.

이러한 지정 방법을 채용 한 배경에는 각 커밋에 따라 작업을 수행해야한다고 생각한다. git log 명령은 작업의 대상이되는 커밋을 찾아내는 방법을 제공하는 것이며, 일반적으로 그런 작업을 할 때의 출발점이다.

사용 예

사용법 섹션에서는 git log의 사용 예를 다수 설명했지만, 하나의 명령에 여러 옵션을 조합하여 지정할 수 있음에 유의하자.

git log --author="John Smith" -p hello.py

이 명령을 실행하면 John Smith가 파일 hello.py 에 적용한 모든 변경의 모든 차이를 표시한다.

문번"…“는 브렌치 비교하는 경우에 자주 사용한다. 다음의 예는 some-feature 브랜치에 있고 master 브랜치에 없는 모든 커밋의 정보를 표시한다.

git log --oneline master..some-feature

1.4 - Git | Git 변경 취소

이 튜토리얼에서는 소프트웨어 개발 프로젝트의 이전 버전에 대한 작업을 할 때 필요한 모든 기술을 학습한다. 최초에 과거 이력의 커밋을 찾는 방법을 보여주고, 공개된 저장소에 게시 된 커밋의 취소 및 로컬 머신에서만 게시된 커밋 취소의 차이를 설명한다.

Git 튜토리얼 : 수정 취소

1.4.1 - Git | Git 변경 취소 | git checkout

git checkout 명령어

git checkout 파일의 체크 아웃, 커밋의 체크 아웃, 브렌치 체크 아웃 3가지 기능을 가진 명령이다. 이 장에서는 처음 두 기능에 대해 설명한다.

커밋을 체크 아웃하면 작업 디렉토리가 그 커밋과 완전히 일치한 상태가 된다. 이 명령은 프로젝트의 현재 상태를 전혀 변경하지 않고 과거의 상태를 확인하는 경우에 사용한다. 파일의 체크 아웃을 하면 작업 디렉토리의 다른 부분에 전혀 영향을 주지 않고 파일의 이전 버전을 확인 할 수 있다.

사용법

git checkout master

master 브랜치로 돌아 가기 명령입니다. 브랜치에 대해서는 다음 장에서 자세히 설명하고 있다. 여기에서는 우선 master 브랜치는 프로젝트의 “현재"상태로 돌아가기 위한 수단이라고만 생각한다.

git checkout <commit> <file>

파일의 이전 버전으로 체크 아웃하는 명령이다. 이 명령을 실행하면 작업 디렉토리에 존재하는 <file>이 입력한 <commit>의 파일 복사본을 스테이지(stage) 영역에 추가한다.

git checkout <commit>

작업 디렉토리의 모든 파일을 지정한 커밋과 동일한 상태로 업데이트하는 명령이다. 인수 <commit> 는 커밋 해시 또는 태그를 사용할 수 있다. 이 명령을 실행하면 “detached HEAD"상태가 된다.

보충 설명

모든 버전 관리 시스템의 배경이되고있는 개념은 프로젝트의 상태를 ‘안전하게’저장하고 코드베이스에 회복 불가능한 손상을 일으킬 가능성을 없애는 것이다. 일단 저장소가 작성되면 git checkout 명령은 저장된 스냅 샷을 로컬 머신에 “로드"하는 간편한 방법이다.

과거의 커밋 체크 아웃은 읽기 전용 작업이다. 과거 버전보기하여 저장소가 영향을 받지는 없다. 프로젝트의 “현재"상태는 일체 변경이 수행하고, master 브랜치에 남아 있다 (자세한 내용은 Git 브랜치 참조). 일반적인 개발 프로젝트가 진행되는 동안 HEAD 보통 master 브랜치 또는 기타 로컬 브랜치를 의미하지만, 과거의 커밋을 체크 아웃하면 HEAD 는 브랜치가 아니라 직접 커밋을 가리 킨다. 이 상태를 “detached HEAD “상태라고 그림으로 설명하면 다음과 같다 :

Git 튜토리얼 : 과거의 커밋 체크 아웃

한편, 과거 파일(커밋을 하지 않은 파일)의 체크 아웃은 저장소의 현재 상태에 영향을 미친다. 지난 버전의 파일(이미 커밋을 하지 않은 파일)은 다른 모든 파일과 함께 새로운 스냅 샷에 재 커밋 할 수 있습니다. 그래서 git checkout 명령은 실질적으로 각각 파일의 변경을 취소하고 되돌리는 기능을 한다.

Git 튜토리얼 : 파일의 이전 버전 체크 아웃

사용 예

이전 버전의 열람

이 예에서는 상식 벗어난 개발을 실험적으로 시작했지만, 그것을 저장할 것인가 여부에 대한 판단을 할 수없는 것으로 가정한다. 그리고 이 판단의 참고로 하기 위해 실험적인 개발을 시작하기 전에 프로젝트의 상태를 확인한다. 먼저 확인하는 버전의 ID를 알아야 한다..

git log --oneline

다음과 같은 프로젝트 내역이 표시된다 :

b7119f2 Continue doing crazy things
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.py
435b61d Create hello.py
9773e52 Initial import

여기에서 git checkout 명령을 사용하여 커밋 메시지가 “Make some important changes to hello.py” 인 것을 커밋의 내용을 확인한다 :

git checkout a1e8fb5

이 명령을 실행하면 작업 디렉토리는 커밋 a1e8fb5 와 똑같은 상태이다. 이 상태에서 프로젝트의 현재 상태에 영향을주지 않고 파일의 열람, 프로젝트의 컴파일, 테스트 실행, 심지어 파일의 편집도 가능하다. 이 상태에서 행해진 작업은 저장소에 일체 저장되지 않는다 . 개발을 계속하려면 프로젝트의 “현재"상태로 반환해야한다 :

git checkout master

여기에서는 디폴트 인 master 브랜치에서 개발 작업을 하고있는 것으로 추정하고 있다 (master 브랜치 내용은 Git 브랜치 참조).

master 브랜치로 돌아온 후 git revert 명령 또는 git reset 명령을 사용하여 필요하다고 판단한 변경을 취소 할 수 있다.

파일 체크 아웃

확인 대상이 특정 파일 인 경우에도 git checkout 명령을 사용하여 파일의 이전 버전을 가져올 수 있다. 예를 들어, 과거의 커밋에 포함되어있는 파일 hello.py 의 내용을 확인하려면 다음 명령을 사용한다 :

git checkout a1e8fb5 hello.py

또한 앞에서 설명한 바와 같이, 커밋 체크 아웃과는 달리,이 명령은 프로젝트의 현재 상태에 영향을 준다 . 과거의 수정 파일은 “Change to be committed"로 표시되고이 파일의 변경 사항을 취소하고 이전 버전으로 되돌릴 수 있다. 과거 버전을 저장할 필요가 없는 경우 다음 명령을 사용하여 최신 버전을 확인한다 :

git checkout HEAD hello.py

1.4.2 - Git | Git 변경 취소 | git revert

git revert 명령

git revert 는 커밋 된 스냅 샷을 취소 명령이다. 다만 프로젝트 이력에서 커밋이 없었던 것으로 하는 것이 아니라 그 커밋에 의해 변경된 내용을 취소하는 방법을 찾아내고 그 결과를 새로운 커밋으로 추가하는 것이다. 이것은 Git의 패키지 이력를 보전하기 위한 것이며, 패키지 이력의 완전성 유지와 협력의 신뢰성 확보를 위한 것이다.

Git 튜토리얼 : git revert

사용법

git revert <commit>

<commit>에서 변경한 모든 변경 사항을 되돌려 새로운 커밋으로 생성하고, 그것을 현재 브랜치에 적용하는 명령이다.

보충 설명

「취소」는 그 커밋을 프로젝트 기록에서 완전히 제거 할 때 사용한다. 이것은 버그를 추적한 결과 어떤 하나의 커밋이 원인인 것으로 판명된 경우 등에 유용한 명령이다. git revert 를 사용하여 수동으로 분석하고 수정하고 그 결과를 새로운 스냅 샷으로 커밋하는 것이 아니라, 그 것을 모두를 자동으로 할 수 있다.

부정 및 취소

git revert는 하나의 커밋만 원래대로 돌리는 명령(부정)이며, 그 커밋 후에 만들어진 모든 커밋을 취소하고 이전의 상태로 돌아가는 명령(취소)이 아님을 확실히 이해하자. Git은 후자 reset 명령이며, revert 명령이 아니다.

Git 튜토리얼 : 부정 및 취소

부정는 취소와 비교하여 두 가지 중요한 이점이 있다. 첫째는 프로젝트 이역 변경이 이루어지지 않기 때문에 이미 공개 저장소에 공개된 커밋에 대해 “안전한"작업이다. 공개된 변경 이력을 변경하는 행위의 위험은 git reset 페이지를 참조해 주길 바란다.

둘째는 git reset 은 현재 커밋을 되돌리는 기능을 뿐이다. 반면 git revert 는 이력에 대해 언제든지 각각의 커밋을 대상으로 할 수 있다는 점이다. 예를 들어, git reset 명령을 사용하여 과거 하나의 커밋만 원래대로 되돌리려고 하면 해당 커밋 이후에 만들어진 모든 커밋과 해당되는 커밋을 삭제하고, 해당 커밋 이후에 만들어진 모든 커밋을 다시 커밋해야 한다. 분명히 이것은 취소 효율적인 방법은 아니다.

사용 예

git revert 명령의 간단한 사용 예를 보여준다. 여기에 있는 스냅 샷을 커밋을 한 이후 바로 취소를 하고 있다.

# Edit some tracked files

# Commit a snapshot
git commit -m "Make some changes that will be undone"

# Revert the commit we just created
git revert HEAD

이것을 그림으로 설명하면 다음과 같다 :

Git 튜토리얼 : git revert의 사용 예

여기에서 4 번째 커밋은 취소 작업 후에도 프로젝트 기록에 남아있는 점에 유의하십시오. git revert 명령은 변경을 취소하기 위하여 그것을 삭제하는 것이 아니라 새로운 커밋을 추가합니다. 그 결과로 3 번째와 5 번째의 커밋 후의 저장소는 완전히 동일한 상태가되고, 게다가 4 번째 커밋은 기록에 남아 있기 때문에 그때로 돌아갈 수 있습니다.

1.4.3 - Git | Git 변경 취소 | git reset

git reset 명령

git revert 명령이 변경 취소 “안전한"방법이라고한다면 git reset 명령은 “위험한"방법이라고 할 수 있습니다. git reset 명령을 사용하여 취소하면 (그리고 ref 나 reflog 의한 참조가 불가능하게 된 경우), 원래 상태로 복원하는 방법은 없습니다. 이 “취소"조작을 취소 할 수없는 것입니다. 이 명령은 Git에서 작업 결과를 잃을 수있는 몇 안되는 명령의 하나이며,이 명령을 사용하는 경우는주의가 필요합니다.

git checkout 명령뿐만 아니라 git reset 도 여러 설정이있는 응용 범위가 넓은 명령입니다. 커밋 된 스냅 샷을 삭제하는 목적으로도 사용되지만, staging 영역과 작업 디렉토리의 변경을 취소하려면 더 사용됩니다. 어쨌든이 명령의 사용은 로컬 변경을 취소 경우에 한한다해야하며, 다른 개발자에 공개 된 커밋의 취소는 결코 가서는 안됩니다.

사용법

git reset <file>

작업 디렉토리에 어떤 변경도 가하지 않고 지정된 파일을 스테이징 영역에서 제거하는 명령입니다. 이 명령을 실행하면 변경 내용을 기록하지 않고 지정된 파일을 제거 스테이지합니다.

git reset

작업 디렉토리에 어떤 변경도 가하지 않고 스테이지 영역을 재설정 직전의 위탁시의 상태와 일치시키는 명령입니다. 이 명령을 실행하면 변경 내용을 기록하지 않고 모든 파일을 제거 무대 한 번 무대 된 스냅 샷을 처음부터 다시 구축 할 수 있습니다.

git reset --hard

스테이지 영역과 작업 디렉토리를 재설정 직전의 위탁시의 상태와 일치시키는 명령입니다. –hard 변경을 제거 스테이지 한 후 추가 작업 디렉토리의 모든 변경 사항을 취소 할을 Git에 지시하는 플래그입니다. 즉, 이것은 커밋 전에 모든 변경을 전혀 없었던 것으로하는 명령이며, 이것을 사용하면 로컬 머신에서 수행 된 개발 작업을 정말 삭제하고 좋은 것인지 아닌지를 확인해야 있습니다.

git reset <commit>

현재 브랜치의 끝을 <commit> 위치로 이동 한 다음 준비 영역을 그 상태와 일치하도록 되돌립니다 만, 작업 디렉토리 만은 그대로 둡니다. <commit> 를 실행 한 후 변경 사항은 작업 디렉토리에 저장되어 더 변경 규모가 작고 정리 된 스냅 샷을 생성하여 로컬 저장소에 다시 커밋을 할 수 있습니다.

git reset --hard <commit>

현재 브랜치의 끝을 <commit> 위치로 이동 한 다음 준비 영역 및 작업 디렉토리를 그 상태와 일치하도록 되돌립니다. 이 명령을 실행하면 커밋 전에 변경 이외에 <commit> 이후에 행해진 모든 커밋도 전혀 없었던 것으로됩니다.

option

  • –soft : index 보존, 작업 트리 보존. 즉 모두 보존.
  • –mixed : index 취소, 작업 트리만 보존 (기본 옵션)
  • –hard : index 취소, 작업 트리 취소. 즉 모두 취소.

보충 설명

위에서 설명한 모든 명령은 저장소에 변경 사항을 제거하는 것입니다. –hard 플래그가 없으면 git reset 변경 제거 스테이지 나 일련의 스냅 샷 커밋 취소를 수행하여 리포지토리를 정리 한 후 그 재 구축하는 수단입니다. –hard 는 개발 중에 한 실험적인 작업의 결과가 바람직하지 않고, 그것을 전혀 없었던 것으로하는 경우에 유용한 명령입니다.

“취소"가 공개 된 커밋을 안전하게 실행 취소 기능을 갖는 반면 git reset 은 로컬 변경을 실행 취소 기능을 가지고 있습니다. 이 두 명령은 목적이 다르기 때문에 그 동작도 달리 “취소"가 변경 기록을 삭제하는 반면, " 취소 “변경 기록을 유지 한 후 복원하는 새로운 커밋합니다.

Git 튜토리얼 : 취소 및 취소

게시 된 내용의 취소는 엄금

<commit>를 실행 한 후 한 번이라도 스냅 샷을 공개 저장소에 푸쉬 한 경우는 git reset <commit> 명령을 사용하여이되지 않습니다. 커밋을 공개하면 다른 개발자가 그것을 전제로 작업을하고 있다고 생각해야합니다.

다른 개발자가 개발 중에 한 커밋을 취소하면 협업에 심각한 문제가 발생할 수 있습니다. 그들이 당신의 저장소와 동기화하려고하면 프로젝트 이력이있는 범위가 누락 된 것 같습니다. 공개 된 커밋을 취소하면 어떻게 될지를 아래의 일련의 그림입니다. 여기에서 origin / master 브랜치는 로컬 master 브랜치에 대응하는 중앙 저장소의 브랜치입니다.

Git 튜토리얼 : 공개 된 커밋 취소

취소 후 신규 커밋하면 Git은 로컬 히스토리가 origin / master 에서 분기 한 것으로 취급 로컬 저장소를 동기화하기 위해 작성되는 병합 커밋이 다른 개발자에 대한 혼란과 작업 방해를 일으 킵니다.

중요한 것은 git reset <commit> 명령을 실행할 때 결과가 신통치 않았다 로컬 실험적인 개발 작업을 취소 할 목적이며, 공개 된 변경 취소를하려한다 을 인식하는 것입니다. 공개 된 커밋을 정정 할 필요가있는 경우는 그 목적의 전용 명령 git revert 가 준비되어 있습니다.

사용 예

파일 제거 단계

git reset 명령은 스테이지 된 스냅 샷을 만들 때 자주 사용됩니다. 다음 예제에서는 hello.py 과 main.py 의 2 개의 파일을 저장소에 이미 추가되어있는 것으로 가정하고 있습니다.

# Edit both hello.py and main.py

# Stage everything in the current directory
git add .

# Realize that the changes in hello.py and main.py
# should be committed in different snapshots

# Unstage main.py
git reset main.py

# Commit only hello.py
git commit -m "Make some changes to hello.py"

# Commit main.py in a separate snapshot
git add main.py
git commit -m "Edit main.py"

볼 수 있듯이, git reset 을 사용하여 다음 커밋과 관련되지 않은 변경을 제거 스테이지, 그 커밋의 목적을 명확히 할 수 있습니다.

로컬 커밋 삭제

다음의 예는 고급 유스 케이스를 보여줍니다. 여기에서는 실험적인 개발을 잠시하고 있다고 가정하고 여러 스냅 샷을 커밋 한 후 그들을 모두 삭제하려면 어떻게해야 하는가를 보여줍니다.

# Create a new file called `foo.py` and add some code to it

# Commit it to the project history
git add foo.py
git commit -m "Start developing a crazy feature"

# Edit `foo.py` again and change some other tracked files, too

# Commit another snapshot
git commit -a -m "Continue my crazy feature"

# Decide to scrap the feature and remove the associated commits
git reset --hard HEAD~2

git reset HEAD ~ 2 는 현재 브랜치를 커밋 2 회분 만 전에 취소 명령이며, 실질적으로는 최근 작성한 두 스냅 샷을 프로젝트 기록에서 삭제하는 기능을합니다. 앞서 언급 한 바와 같이 이러한 reset 명령의 사용 대상은 미공개 커밋 제한한다. 커밋을 공개 저장소에 푸시하는 경우에는 결코 위의 작업을 수행 할 수 없습니다.

다양한 사용 예

index 추가 취소

해당 파일을 index에 추가한 것을 취소한다. (unstage)
작업 트리의 변경내용은 보존된다.

git reset [파일명] 
git reset HEAD [파일명]

commit 취소

최종 커밋을 취소하고, 작업 트리는 보존된다. commit은 했으나 push하지 않은 경우 유용하다.

git reset HEAD^

마지막 2개의 커밋을 취소하고, 작업 트리는 보존된다.

git reset HEAD~2

마지막 2개의 커밋을 취소하고, index 및 작업 트리 모두 원복된다.

git reset --hard HEAD~2

머지한 것을 이미 커밋했을 때, 그 commit을 취소한다. 잘못된 merge를 이미 커밋한 경우 유용하다.

git reset --hard ORIG_HEAD

HEAD에서 변경한 내역을 취소하는 새로운 commit 발행한다. (undo commit)
commit을 이미 push 해버린 경우 유용하다.

git revert HEAD

워킹트리 전체 원복

워킹트리 전체를 마지막 커밋 상태로 되돌린다.
마지막 commit 이후의 작업 트리와 index의 수정사항 모두 사라진다.
변경을 커밋하지 않았다면 유용하다.

git reset --hard HEAD

1.4.4 - Git | Git 변경 취소 | git clean

git clean 명령

git clean 은 작업 디렉토리에서 추적되지 않는 파일을 삭제하는 명령입니다. git status 명령을 사용하여 추적 대칭 않는 파일을 확인하고 수동으로 그들을 제거하는 것은 간단하므로이 명령은 어느 쪽 일까하고 말하면 편의성을 높이기 위해 마련된 것입니다. 일반 rm 명령 마찬가지로 git clean 명령을 취소 할 수없는 때문에이 명령을 실행 할 때 그 추적되지 않는 파일을 정말 삭제해도 좋은지 여부를 다시 확인하십시오.

git clean 은 git reset –hard 명령과 잘 결합됩니다. 이미 설명했듯이 reset 명령이 작용하는 것은 추적 대상이되고있는 파일 만 있기 때문에 추적되지 않는 파일을 정리하기 위해 다른 명령이 필요할 것입니다. 이 두 명령을 함께 사용하여 작업 디렉토리를 특정 커밋 시점과 완전히 동일한 상태로 되돌릴 수 있습니다.

사용법

git clean -n

git clean의 ‘예행 연습’을하는 명령입니다. 이 명령을 실행하면 삭제 된 파일을 표시하지만 실제 삭제되지 않습니다.

git clean -f

추적되지 않는 파일을 현재 디렉토리에서 삭제하는 명령입니다. 설정 옵션 clean.requireForce 이 false 로 설정되지 않은 경우 (이 옵션은 기본적으로 true 입니다)는 -f (force) 플래그는 필수입니다. 이 명령은 추적되지 않는 폴더 나 파일도 .gitignore. 로 지정한 것은 삭제 하지 않습니다 .

git clean -f <path>

추적되지 않는 파일을 삭제하지만, 그 범위는 지정된 경로에 한정하는 명령입니다.

git clean -df

현재 디렉토리에서 추적되지 않는 파일 및 추적 대상에서 제외 디렉토리를 삭제합니다.

git clean -xf

현재 디렉토리에서 추적되지 않는 파일 및 Git은 보통 무시되는 파일을 삭제합니다.

보충 설명

git reset –hard 와 git clean -f 두 명령은 로컬 저장소에서 결과의 쇠약 작업을 실시했기 때문에 그것을 없었던 것으로하는 경우에 매우 자주 사용됩니다. 이 두 명령을 실행하면 작업 디렉토리의 상태는 직전의 위탁을 한 시점을 기준으로 돌아가서 그 상태에서 작업을 다시 시작할 수 있습니다.

git clean 빌드 완료 후 작업 디렉토리를 정리하는 경우에도 유용한 명령입니다. 예를 들어이 명령을 실행하면 C 컴파일러가 생성 한 .o 나 .exe 바이너리 파일을 쉽게 제거 할 수 있습니다. 이 작업은 릴리스를 목표로 프로젝트를 패키징 할 때 필수가되는 경우가 있습니다. -x 는이 목적에 유용한 옵션입니다.

또한 git clean 명령이 git reset 명령과 함께 커밋의 내용을 완전히 삭제 해 버리는 몇 Git 명령 중 하나이며, 사용에주의가 필요하다는 것을 잊어서는 안됩니다. 실제로 중요한 커밋의 내용을 잃어 버리는 일이 매우 많기 때문에, 기본적인 조작 임에도 불구 Git 메인테이너가 -f 플래그 지정을 필수 설정하는 일이 자주 있습니다. 이를 설정하는 것이 간단한 git clean 을 실행하여 실수로 모든 것을 잃는 것을 방지 할 수 있습니다.

사용 예

다음 예제는 생성 된 새 파일을 포함하여 작업 디렉토리의 모든 변경 사항을 취소합니다. 여기에서는 이미 여러 스냅 샷을 다하고 있으며, 또한 새로운 실험적인 개발의 중간에 있다고 가정합니다.

# Edit some existing files
# Add some new files
# Realize you have no idea what you're doing

# Undo changes in tracked files
git reset --hard

# Remove untracked files
git clean -df

이 일련의 reset / clean 명령을 실행하면 작업 디렉토리 및 스테이징 영역은 직전의 위탁시와 완전히 동일하게, git status 명령을 실행하면 작업 디렉토리의 내용이 정리 될 취지를 표시합니다. 따라서이 상태에서 다시 시작 할 수 있습니다.

또한 git reset 섹션의 두 번째 예와는 달리 만들어진 새로운 파일 저장소 무대 된 적이 한 번도없는 것으로 유의하십시오. 그 결과이 새로운 파일은 추적 대상이되지 않기 때문에 git reset –hard 명령의 영향을받지 않고 삭제하려면 git clean 명령이 필요합니다.

1.5 - Git | Git 브랜치

이 튜토리얼에서는 Git 브랜치에 대한 포괄적 인 소개입니다. 먼저 프로젝트 이력의 새로운 전개라고도 말할 지점 작성에 대한 개관합니다. 다음 지점을 선택할 때 git checkout 명령의 사용법을 설명합니다. 마지막으로, 독립적 인 지점의 기록을 통합하기위한 git merge 명령의 사용법을 배웁니다.

읽기 진행에 따라 Git 브랜치는 SVN 브랜치와는 다른 것임이 이해할 수 있다고 생각합니다. SVN 브랜치가 작업 성과를 때때로 대규모 정리하기위한 것 인 반면 Git 브랜치는 일상적인 워크 플로우에서 필수적인 요소입니다.

Git 튜토리얼 : 분기 및 병합

1.5.1 - Git | Git 브랜치 | git branch

git branch 명령어

지점과는 독립적인 개발 라인을 의미하ㄴ다. 지점이 튜토리얼 시리즈의 첫 번째 챕터 인 Git의 기본 설명한 편집 / 스테이지 / 커밋 프로세스에 대한 추상적 개념이다. 이것은 작업 디렉토리 및 스테이징 영역 프로젝트 기록을 전적으로 창조하는 수단이라고 생각할 수도 있다. 새 커밋은 현재 브랜치의 이력에 기록되어 프로젝트 이력의 분기를 형성한다.

git branch는 분기 생성, 보기, 이름 변경, 삭제하는 명령이다. 이 명령은 브랜치를 전환하는 기능도 분기 한 이력을 통합하고 실행 취소 기능도 없다. 따라서 git branch 명령은 많은 경우 git checkout 명령과 git merge 명령과 함께 사용된다.

사용법

git branch

저장소의 모든 지점을 나열한다.

git branch <branch>

<branch> 라는 이름의 새 지점을 만든다. 새로 생성 된 브란트의 체크 아웃되지 않는다.

git branch -d <branch>

지정한 지점을 삭제한다. 지점에 병합되지 않은 변경이 남아있는 경우는 Git이 삭제를 거부하기 때문에 이 명령은 “안전한” 작업이다.

git branch -D <branch>

지정한 지점에 병합되지 않은 변경이 남아 있었다고 해도 이를 강제로 삭제하는 명령이다. 이 명령은 특정 개발 라인에서 만들어진 모든 커밋을 완전히 삭제하려는 경우에 사용한다.

git branch -m <branch>

현재 브랜치의 이름을 <branch>으로 변경한다.

보충 설명

Git은 브랜치는 일상적인 개발 프로세스의 요소이다 새로운 기능 개발 및 버그 수정을 할 경우 그 규모의 대소를 불문하고 변경을 캡슐화하는 지점을 만든다. 이는 불안정한 코드가 메인 코드베이스에 커밋되는 것을 방지하고 또한 master 브랜치에 병합하기 전에 기능의 기록을 정리 할 수 ​​있다.

Git 튜토리얼 : git branch 예를 들어, 위의 그림은 작은 기능 개발과 장기의 기능 개발을 지원하는 두 개의 독립적 인 개발 라인을 갖는 저장소를 시각화 한 것이다 이러한 개발 작업을 분기함으로써이 둘을 동시에 진행시킬 수있는뿐만 아니라 기본 master 브랜치 를 불완전한 코드로부터 보호 할 수 있다.

분기 끝

Git 브랜치의 배경에있는 설계 사상은 SVN에서 분기보다 훨씬 가벼운 것이다 SVN에서 디렉토리간에 직접 파일을 복사 할 반면 Git의 브랜치는 커밋에 대한 참조로 저장됩니다. 이런 의미에서 브랜치는 커밋 컨테이너가 아닌 일련의 노력의 끝 을 나타내는 것이라고 말할 수 있다. 하나의 브랜치의 기록은 커밋의 상호 관계를 통해 외부 삽됩니다.

이 것은 Git 병합 모델에 매우 큰 영향을 미친다. SVN의 병합은 파일 기반에서 이루어지는 반면 Git은 커밋을 추상화 수준에서 작업을 수행한다. 사실, 프로젝트 이력의 병합은 독립적 확약 기록 결합이라고 생각할 수 있다.

사용 예

지점 만들기

분기가 단순한 커밋에 대한 포인터 임을 이해할 필요가 있다. 브랜치를 생성했다고 해도, Git이 할 포인터의 생성이며, 저장소를 변경할 수 없다. 따라서 먼저 아래 그림과 같은 저장소가 있다고 한다 :

그리고 다음의 명령을 사용하여 분기를 작성하는 것으로 한다 :

git branch crazy-experiment

여기에서는 저장소의 기록에는 아무런 변경도 이루어지지 않습니다. 새롭게 만들어지는 것은 현재 커밋에 대한 포인터 만 :

Git 튜토리얼 : 신규 지점 만들기

이 작업은 단순히 신규 지점을 만든 뿐임을 명심하자. 이 지점에 커밋 추가를 시작하기 위해서는 git checkout 명령을 사용하여 그것을 선택해야 다음에 일반 git add 명령과 git commit 명령을 사용한다. 자세한 내용은 이 장의 git checkout 을 참조한다

지점 삭제

지점에서의 작업이 완료 master 브랜치에 병합이 완료되면 지점을 삭제 기록을 잃지 않는다 :

git branch -d crazy-experiment

그러나 지정된 지점의 병합이 완료되지 않은 경우 위 명령을 실행하면 오류 메시지가 나타난다 :

error: The branch 'crazy-experiment' is not fully merged.
If you are sure you want to delete it, run 'git branch -D crazy-experiment'.

따라서 이러한 커밋에 대한 참조의 상실, 즉 작은 과실에 의한 개발 라인 전체에 대한 액세스 수단의 상실을 방지 할 수 있다. 브랜치를 삭제해도 좋다는 확신이있는 경우 (예를 들어 그 지점에서 실시한 실험적인 개발이 실패했을 경우)는 대문자 -D 플래그를 사용한다 :

git branch -D crazy-experiment

이 명령을 실행하면 브랜치의 상태에 관계없이 어떠한 경고없이 삭제하는 신중하게 사용해야 한다.

Git Branch 종류

Master Branch

  • 제품으로 출시될 수 있는 브랜치
  • 배포(Release) 이력을 관리하기 위해 사용. 즉, 배포 가능한 상태만을 관리한다.

Develop Branch

  • 다음 출시 버전을 개발하는 브랜치
  • 기능 개발을 위한 브랜치들을 병합하기 위해 사용. 즉, 모든 기능이 추가되고 버그가 수정되어 배포 가능한 안정적인 상태라면 develop 브랜치를 ‘master’ 브랜치에 병합(merge)한다.
  • 평소에는 이 브랜치를 기반으로 개발을 진행한다.

Feature branch

  • 기능을 개발하는 브랜치
  • feature 브랜치는 새로운 기능 개발 및 버그 수정이 필요할 때마다 ‘develop’ 브랜치로부터 분기한다. feature 브랜치에서의 작업은 기본적으로 공유할 필요가 없기 때문에, 자신의 로컬 저장소에서 관리한다.
  • 개발이 완료되면 ‘develop’ 브랜치로 병합(merge)하여 다른 사람들과 공유한다.

Release Branch

  • 이번 출시 버전을 준비하는 브랜치
  • 배포를 위한 전용 브랜치를 사용함으로써 한 팀이 해당 배포를 준비하는 동안 다른 팀은 다음 배포를 위한 기능 개발을 계속할 수 있다. 즉, 딱딱 끊어지는 개발 단계를 정의하기에 아주 좋다.
  • 예를 들어, ‘이번 주에 버전 1.3 배포를 목표로 한다!’라고 팀 구성원들과 쉽게 소통하고 합의할 수 있다는 말이다.

Hotfix Branch

  • 출시 버전에서 발생한 버그를 수정 하는 브랜치
  • 배포한 버전에 긴급하게 수정을 해야 할 필요가 있을 경우, ‘master’ 브랜치에서 분기하는 브랜치이다. ‘develop’ 브랜치에서 문제가 되는 부분을 수정하여 배포 가능한 버전을 만들기에는 시간도 많이 소요되고 안정성을 보장하기도 - - 어려우므로 바로 배포가 가능한 ‘master’ 브랜치에서 직접 브랜치를 만들어 필요한 부분만을 수정한 후 다시 ‘master’브랜치에 병합하여 이를 배포해야 하는 것이다.-

1.5.2 - Git | Git 브랜치 | git checkout

git checkout 명령어

git checkout 은 git branch 명령에 의해 생성 된 지점 사이를 이동하는 명령입니다. 지점의 체크 아웃을 수행하여 작업 디렉토리의 파일이 해당 분기에 저장되어있는 버전으로 업데이트 된 후 모든 새 커밋은 해당 분기에 기록됩니다. 이 명령은 작업 개발 라인을 선택하는 수단이라고 생각할 수 있습니다.

앞 장 에서 과거의 커밋을 볼 경우 git checkout 명령의 사용법을 설명했습니다. 지점의 체크 아웃은 지정된 지점 또는 버전에 일치하도록 작업 디렉토리가 업데이트된다는 점에서는 비슷하지만 작업 디렉토리에 변경 사항이 남아 있다면 그것이 프로젝트 기록에 저장 된다 라는 점이 다릅니다. 즉이 명령은 읽기 전용 조작은 없다.

사용법

git checkout <existing-branch>

git branch 명령을 사용하여 만든 브랜치를 체크 아웃하는 명령입니다. 이 명령을 실행하면 <existing-branch>가 현재 브랜치가되고, 그것 일치하도록 작업 디렉토리가 업데이트됩니다.

git checkout -b <new-branch>

신규 지점 <new-branch>를 작성하여 즉시 체크 아웃하는 명령입니다. -b 플래그는 git branch <new-branch> 명령을 실행 한 다음 git checkout <new-branch> 을 실행하기 편리한 플래그입니다.

git checkout -b <new-branch> <existing-branch>

상기 명령과 동일한 기능이지만, 그러나 현재 브랜치가 아니라 <existing-branch> 새 분기 기점으로합니다.

보충 설명

git checkout 은 git branch 명령과 함께 명령입니다. 새로운 기능 개발을 시작하는 경우 git branch 명령을 사용하여 분기를 만든 다음 git checkout 명령을 사용하여 그것을 체크 아웃합니다. 하나의 저장소에서 git checkout 명령을 사용하여 기능을 전환하여 여러 기능의 개발 작업을 할 수 있습니다.

Git 튜토리얼 : git checkout을 사용하여 하나의 저장소 내에서 여러 기능 전환.

개별 기능에 대해 각각 전용 지점을 설치함으로써 SVN을 기반으로 기존의 워크 플로우와는 크게 다른 기술이 제공 할 수 있습니다. 이에 따라 기존의 기능을 손상 우려를 발생하지 않고 새로운 실험적인 개발을 할 쉽게 가능하며, 또한 관련이없는 여러 기능 개발을 동시에 수행 할 수있게되었습니다. 이외에 지점의 도입으로 여러 협업 워크 플로우를 쉽게 채용 할 수있게되었습니다.

Detached HEAD

git checkout 세 가지 사용법을 학습했기 때문에 여기에서 앞 장에서 언급 한 “detached HEAD “에 대해 설명하고 둡시다.

앞서 언급 한 바와 같이, HEAD 는 Git에서는 현재 스냅 샷의 참조를 의미하고 git checkout 을 실행하면 HEAD 포인트 위치를 지정하는 지점 또는 커밋으로 이동합니다. 포인트 처가 지점이면 아무 문제가 없지만 커밋을 체크 아웃 한 경우에는 “detached HEAD “상태로 전환됩니다.

Git 튜토리얼 : Detached Head

이것은이 상태에서 수행 된 작업은 모든 프로젝트의 다른 개발 작업과 “분리되어있다"고 경고하는 것입니다. detached HEAD 상태 기능 개발을 시작해서 거기로 돌아가 지점은 생성되지 않습니다. (예를 들면 기능을 병합 할 생각으로) 다른 브랜치를 체크 아웃 해 버리면 그 기능을 참조 할 수 없습니다 :

Git 튜토리얼 : Detached Head 상태

중요한 것은 개발 작업은 항상 지점에서 실시하여야하며, detached HEAD 에 가서는 안된다는 점입니다. 이것은 커밋에 대한 참조 방법을 항상 보장하는 것입니다. 그러나 과거의 커밋을 볼 뿐이라면, detached HEAD 상태 여부를 걱정할 필요는 없습니다.

사용 예

다음 예제는 Git의 브랜치의 기본적인 사용법을 보여줍니다. 새로운 기능 개발 작업을 시작하는 경우 전용 브랜치를 만들고 그것으로 전환합니다 :

git branch new-feature
git checkout new-feature

이렇게함으로써 이전 장에서 설명한 것처럼 새로운 스냅 샷 커밋이 가능합니다 :

# Edit some files
git add <file>
git commit -m "Started work on a new feature"
# Repeat

커밋은 모두 master 브랜치는 독립적 인 new-feature 브랜치에 기록됩니다. 이 상태에서 얼마든지 위탁이 가능하며, 이때 다른 브랜치를 걱정할 필요가 없습니다. “공식"코드베이스에서의 작업으로 돌아가려면 단순히 master 브랜치 체크 아웃을하면 되나요 :

git checkout master

이 명령을 실행하면 기능 개발 작업을 시작하기 전에 저장소의 상태가 표시됩니다. 여기 완료된 기능 병합 새 브랜치를 만들고, 다른 기능의 시작 공식 코드 기반에 대한 작업 등을 할 수 있습니다.

1.5.3 - Git | Git 브랜치 | git merge

git merge 명령어

병합은 Git에서 분기 한 내용을 다시 통합하는 방법입니다. git merge 는 git branch 명령을 사용하여 만든 독립 한 복수의 개발 라인을 하나의 브랜치에 통합하는 명령입니다.

여기서 아래에서 설명하는 모든 명령은 현재 브랜치에 병합 할 것임에 유의하십시오. 현재 브랜치는 병합 결과 업데이트되지만 대상 지점 (인수에서 지정한 지점)은 그대로 유지됩니다. 따라서, git merge 명령은 보통 브랜치를 선택 git checkout 명령 및 필요하지 않은 대상 지점을 삭제 git branch -d 명령과 함께 사용됩니다.

사용법

git merge <branch>

지정한 브랜치를 현재 브랜치에 병합하는 명령입니다. Git은 병합 알고리즘은 자동으로 선택됩니다 (아래에서 설명합니다).

git merge --no-ff <branch>

지정한 브랜치를 현재 브랜치에 병합하지만 그 때 항상 (비록 그것이 “빨리 감기"가능하더라도) 병합 커밋을 생성하고 병합합니다. 이 명령은 저장소에서 발생한 모든 병합을 기록하는 경우에 유용합니다.

보충 설명

독립적 인 지점에서 기능 개발 작업이 완료되면, 그것을 메인 코드베이스에 반영시킬 필요가 생깁니다. Git은 이렇게 있어서는 저장소의 구성 상태에 따라 여러 가지 알고리즘 (빨리 감기 병합 및 3-way 병합)가 준비되어 있습니다.

앞으로 병합 은 현재 브랜치의 끝에서 목표 지점을 향해 1 개의 직선 인 경로 만 다니고있는 경우에 적용됩니다. 이 경우 실제로 병합이되는 것은 아니고, 단지 현재 브랜치의 끝을 대상 분기의 끝으로 이동시킴으로써 (즉 “빨리 감기"에 의해) 통합이 이루어집니다. 이에 따라 실질적으로 기록 결합이 이루어 대상 지점에서 액세스 가능했던 커밋이 모든 브랜치에서 액세스 할 수 있습니다. 예를 들어 아래 그림은 some-feature 브랜치를 master 브랜치로 앞으로 병합 한 예를 보여줍니다 :

Git 튜토리얼 : 앞으로 병합

그러나 분기가 분기하는 경우는 앞으로 병합을 적용 할 수 없습니다. 경로가 대상 지점으로 향하는 1 개만 아니기 때문에 기록을 결합하는 방법은 세 방향 병합 이외에는 없습니다. 세 방향 병합은 두 기록을 결합하기 위하여 전용의 커밋이 생성 실행됩니다. 이 명칭은 3 개의 커밋 (두 분기의 각 끝의 커밋과 공통 조상 인 커밋)를 사용하여 병합 커밋을 생성하는 것으로부터 비롯됩니다. Git 튜토리얼 : 3-way 병합

이 두 병합 알고리즘 모두 사용 가능하지만, 많은 개발자는 작은 기능과 버그 수정에 ( 로 Rebase 를 사용했다) 앞으로 병합을 장기에 걸쳐 진행된 기능에는 세 방향 병합 사용하는 경향이 있습니다. 후자의 경우, 생성 된 병합 커밋은 두 지점의 상징적 결합으로 작동합니다.

충돌 해결

병합하려고하고있는 두 지점에서 동일 파일의 동일한 부분에 변경이있는 경우, 어느 버전을 사용할 것인지를 Git 측에서 판단 할 수 없습니다. 그런 상황이되었을 경우 병합 커밋 생성의 앞에서 정지하여 수동으로 충돌 해결을 촉구합니다.

Git 병합 프로세스가 뛰어나다는 병합시 충돌을 해결 편집 / 스테이지 / 커밋하는 일반적인 워크 플로우를 사용할 수 있다는 것입니다. 병합시 충돌이 발생하는 경우는 git status 명령을 실행하면 충돌을 해결해야 파일이 표시됩니다. 예를 들어 두 지점에서 hello.py 의 동일한 부분이 변경되지 않으면 다음과 같은 정보가 표시됩니다 :

# On branch master
# Unmerged paths:
# (use "git add/rm ..." as appropriate to mark resolution)
#
# both modified: hello.py
#

여기에서 병합 할 내용을 확인하여 필요한 수정을합니다. 수정이 끝난 병합을 수행 할 준비가되면 git add 명령을 사용하여 충돌이 발생한 파일을 스테이징 영역에 추가합니다. 이어 일반 git commit 명령을 사용하여 병합 커밋을 만듭니다. 이 과정은 일반 스냅 샷 커밋과 완전히 동일하기 때문에 일반 개발자 병합 작업은 알기 쉬운 것으로되어 있습니다.

또한 병합시 충돌이 일어나는 것은 세 방향 병합의 경우 뿐이다 것을 명심하십시오. 앞으로 병합으로 변경이 충돌을 일으킬 수는 없습니다.

git merge사용 예

앞으로 병합

먼저 앞으로 병합의 예를 보여줍니다. 다음 코드에서는 새 브랜치를 만들고이 두 커밋을 넣고 마지막으로 앞으로 병합하여 그것을 master 브랜치에 통합하고 있습니다.

# Start a new feature
git checkout -b new-feature master

# Edit some files
git add <file>
git commit -m "Start a feature"

# Edit some files
git add <file>
git commit -m "Finish a feature"

# Merge in the new-feature branch
git checkout master
git merge new-feature
git branch -d new-feature

이것은 (장기의 기능 개발을 행하기위한 대규모 조직을위한 브랜치가 아닌) 독립적 인 소규모 개발을위한 단기간의 기능 가지를 사용하는 경우의 일반적인 흐름입니다.

또한 new-feature 브랜치는 master 브랜치에서 액세스 가능하기 때문에 git branch -d 명령을 사용하여 경고가 표시되지 않습니다.

세 방향 병합

다음 예제는 이전 예제와 비슷하지만 기능이 진행되는 동안 master 도 진행하고 있기 때문에 세 방향 병합이 필요합니다. 이 시나리오는 대규모 기능의 경우와 프로젝트에서 여러 개발자들이 동시에 작업을 수행하는 경우에 자주 발생합니다.

# Start a new feature
git checkout -b new-feature master

# Edit some files
git add <file>
git commit -m "Start a feature"

# Edit some files
git add <file>
git commit -m "Finish a feature"

# Develop the master branch
git checkout master

# Edit some files
git add <file>
git commit -m "Make some super-stable changes to master"

# Merge in the new-feature branch
git merge new-feature
git branch -d new-feature

이 경우 퇴보를하지 않고 master 를 new-feature 로 이동 할 수 없기 때문에 앞으로 병합 실행이 불가능하다는 것을 명심하십시오.

일반적인 워크 플로는 new-feature 사실은 장기간의 개발을 필요로하는 대규모 기능인 경우가 많고, 그 사이에 master 에 새로운 커밋이 추가되는 경우가 종종 있습니다. 기능 가지 실제로도 위의 예와 같이 소규모 인 경우는 아마도 그것을 master 으로 업데이트하여 앞으로 병합하는 쪽을 선택해야합니다. 이 방법은 불필요한 병합 커밋을 줄이고 프로젝트 이력의 합병증을 방지합니다.

1.6 - Git | Git의 기록 갱신

G it의 주요 목적은 커밋 된 변경을 잃지 않고 기록 해 나가는 것입니다. 하지만 Git은 개발 워크 플로우를 완벽하게 만들어 바꾸는 기능도 갖추고 있습니다. 이러한 기능은 프로젝트의 기록 명백한 재 작성 기능도 포함되지만 그러나이를 위해 커밋 정보를 잃을 가능성도 생깁니다. Git은 기록 갱신하는 명령을 프로젝트의 내용을 잃을 가능성이 에게 경고문 함께 제공합니다.

이 장에서는 커밋 된 스냅 샷을 재 작성해야 할 이유 중 일반적으로 자주 일어나는 것으로 설명하고 그것을 실행할 때의 사고를 어떻게하고 방지하는 방법을 보여줍니다.

1.6.1 - Git | Git의 기록 갱신 | git commit --amend

git commit –amend 명령어

git commit –amend 은 이전 커밋을 수정하는 경우에 유용한 명령입니다. 이 명령을 실행하면 전혀 새로운 스냅 샷을 커밋하는 것이 아니라 스테이지 된 변경 내용과 직전의 위탁의 결합이 이루어집니다. 또한 스냅 샷에 변경을 가하지 않고 단순히 이전 커밋 메시지를 편집하는 경우에도 유용합니다.

Git 튜토리얼 : git commit –amend

그러나 직전의 위탁의 수정은 그것을 덮어 쓰는 것이 아니라, 전혀 다른 커밋으로 바꿀 것을 의미합니다. Git은 그것이 위 그림에서 별표 (*)와 같이 새로운 커밋처럼 보입니다. 공개 저장소에 대한 작업을 할 경우이 사실을 기억해야합니다.

사용법

git commit --amend

스테이지되는 내용을 직전의 위탁과 결합하고 그 결과 생성 된 스냅 샷 직전의 위탁을 대체 명령입니다. 스테이지 영역에 아무것도없는 상태에서이 명령을 실행하면 스냅 샷을 다시 작성하지 않고 이전 커밋 메시지 편집을 할 수 있습니다.

보충 설명

개발 현장에서는 불완전한 커밋이 수행 될 수 일상적으로 발생합니다. 파일의 무대를 잊거나 커밋 메시지의 형식 지정을 잘못 할 경우가 종종 있습니다. –amend 플래그는 이러한 가벼운 실수를 수정하는 경우에 유용합니다.

공개 된 커밋의 수정은 금지

git reset 페이지에서 다른 개발자와 공유중인 위탁의 취소를해서는 안되는 이유를 설명했습니다. 수정도 마찬가지가 성립 공개 저장소에 푸시 된 커밋의 수정을해서는 안됩니다.

수정 된 커밋은 실제로 완전히 새로운 커밋이며 이전의 커밋은 프로젝트의 기록에서 삭제됩니다. 이것은 공개 된 커밋을 취소 한 경우와 유사한 문제를 일으 킵니다. 다른 개발자가 이미 작업의 기반으로 사용하는 커밋을 수정하면 그들의 작업의 기반이 손실 된 것 같습니다. 이것은 개발자에게 혼란을 가져, 그 때의 회복은 귀찮습니다.

사용 예

다음 예제에서는 Git 기반의 개발에있어서 일반적인 시나리오를 보여줍니다. 두 파일을 편집하여 하나의 스냅 샷으로 커밋 할 예정 이었지만 먼저 커밋 할 때 한쪽의 파일을 추가하는 것을 잊지합니다. 이 수정을 위해서는, 단순히 파일을 스테이지하고 –amend 플래그를 지정하고 커밋하면 되나요 :

# Edit hello.py and main.py
git add hello.py
git commit

# Realize you forgot to add the changes from main.py
git add main.py
git commit --amend --no-edit

이전 커밋 메시지를 표시하기 위해서는 편집기가 사용되며, 또한 –no-edit 플래그를 지정하면 커밋 메시지를 변경하지 않고 커밋 수정을 할 수 있습니다. 필요하다면 그것을 수정하고 평소와 같이 파일을 저장하고 닫습니다. 결과로 생성되는 커밋은 불완전한 커밋을 대체 hello.py 과 main.py 에 변경 내용을 하나의 스냅 샷으로 저지른 것처럼 보입니다.

1.6.2 - Git | Git의 기록 갱신 | git rebase

git rebase 명령

로 Rebase는 지점의 기점이되는 커밋을 다른 커밋으로 이동하는 작업입니다. 일반적인 동작을 다음 그림과 같습니다 :

Git 튜토리얼 : 프로젝트 기록 선형성을 유지하기로 Rebase.

외관상은로 Rebase는 커밋에서 다른 커밋 지점을 이동하는 수단에 지나지 않습니다. 하지만 Git의 내부에서는 새로운 커밋을 생성하고 그것을 대상 기반 커밋에 적용하여이를 행하고있어 이는 곧 그대로 프로젝트 기록 갱신을하고있는 것입니다. 여기에서는 지점 자체는 같은 것이 보이지도 그것을 구성하는 노력은 전혀 다르다는 것을 이해하는 것이 중요합니다.

사용법

git rebase <base>

현재의 지점을 <base>으로 업데이트하는 명령에로 Rebase 대상으로 모든 종류의 커밋 참조 (커밋 ID, 브랜치, 태그, HEAD 에 대한 상대 참조)를 사용할 수 있습니다.

보충 설명

로 Rebase의 주요 목적은 프로젝트 기록 선형성을 유지하는 것입니다. 예를 들어, 기능에서 작업 시작 후 master 브랜치에 진행이 있었다 시나리오를 고려하십시오 :

기능을 master 브랜치에 통합하려면 직접 병합과로 Rebase 후 병합의 두 가지 방법이 있습니다. 첫번째 옵션을 선택하면 세 방향 병합 및 커밋이 필요한 반면, 후자는 앞으로 병합이 가능하며 기록 선형성은 완벽하게 유지됩니다. 다음 그림은 master 에이 버전이 앞으로 병합이 가능해진다 이유를 설명하고 있습니다.

Git 튜토리얼 : 앞으로 병합

로 Rebase는 상류 측의 변경을 로컬 저장소에 통합하는 일반적인 방법입니다. git merge 명령을 사용하여 상류 측의 변경 사항을 검색하는 경우 프로젝트의 진행 상황을 확인할 때마다 불필요한 병합 커밋이 생성됩니다. 이에 대해로 Rebase는 “내 변경 작업은 모두 변경을 완료 한 것을 기반으로하고 싶다"는 동등입니다.

공개 저장소로 Rebase는 엄금

git commit –amend 및 git reset 명령의 설명과 같이 공개 저장소에 푸시 된 커밋로 Rebase하지 안됩니다. 로 Rebase는 과거의 커밋을 새로운 커밋으로 바꿀 것이며, 프로젝트 이력의 일부가 누락 된 것 같습니다.

사용 예

다음 예제는 프로젝트의 선형성을 유지하기 위해 git rebase와 git merge를 병용 한 것입니다. 이것은 빠르고 확실하게 빨리 감기 병합하는 간편한 방법입니다.

# Start a new feature
git checkout -b new-feature master
# Edit files
git commit -a -m "Start developing a feature"

기능 개발 중에 코드 기반 보안 취약점이 발견되었다고합니다.

# Create a hotfix branch based off of master
git checkout -b hotfix master
# Edit files
git commit -a -m "Fix security hole"
# Merge back into master
git checkout master
git merge hotfix
git branch -d hotfix

hotfix를 master에 병합하면 프로젝트 기록에는 분기가 발생합니다. 그래서 단순히 git merge 명령을 사용하는 것이 아니라,이 버전이 기록 선형성을 유지하면서 수수료 추 통합합니다 :

git checkout new-feature
git rebase master

따라서 new-feature는 master 끝으로 이동했기 때문에 master와 일반 감기 병합이 가능합니다 :

git checkout master
git merge new-feature

1.6.3 - Git | Git의 기록 갱신 | git rebase -i

git rebase -i 명령어

git rebase 를 -i 플래그를 지정하여 실행하면 대화 형 리베이스 세션이 시작됩니다. 인터랙티브로 Rebase는 모든 커밋을 그대로 새로운베이스로 이동하는 것이 아니라 대상이되는 개별 커밋의 변경이 가능합니다. 이것을 사용하여 기존 일련의 커밋 삭제, 분할, 수정을하고 기록을 정리 할 수 있습니다. 이것은 단지 git commit –amend 명령의 향상된 버전이라고 할 수 있습니다.

사용법

git rebase -i <base>

인터랙티브 리 기반 세션을 사용하여 현재 지점을 으로 업데이트하는 명령입니다. 이 명령을 실행하면 편집기가 열리고로 Rebase하는 각 커밋에 대한 명령 (아래에서 설명합니다)의 입력이 가능합니다. 여기서 명령은 각 커밋을 새로운 기점으로 이동하는 방법을 지정합니다. 또한 편집기에서 커밋 순서를 직접 편집하여 커밋 순서를 정렬 할 수 있습니다.

보충 설명

인터랙티브로 Rebase 사용하여 기록 겉보기에 대한 완전한 만들고 변경 할 수 있습니다. 이 기능은 코드 개발 중에 지저분한 커밋을 반복 한 기록이 남아있다하더라도 사후에 그것을 검토하고 구성 할 수 있기 때문에 개발자는 상당한 자유가 손에 들어갑니다.

대부분의 개발자는 master 브랜치에 병합하기 전에 기능 지점을 깔끔하게 보이게하기 위해 인터랙티브로 Rebase 사용하는 경향이 있습니다. 인터랙티브로 Rebase 사용하면 중요하지 않은 커밋을 한 덩어리로 불필요한 커밋을 삭제하고 다른 모든 것을 정리하고 “공식적인"저장소에 커밋 할 수 있습니다. 사정을 모르는 사람에게는이 기능 개발이 전체적으로 잘 계획된 커밋 1 개의 계열로 순조롭게 진행 한 것처럼 보입니다.

사용 예

아래의 예는 대화 형이 아닌 git rebase 명령의 설명 페이지에 있던 예를 대화 형 명령의 경우 다시 작성합니다.

# Start a new feature
git checkout -b new-feature master
# Edit files
git commit -a -m "Start developing a feature"
# Edit more files
git commit -a -m "Fix something from the previous commit"

# Add a commit directly to master
git checkout master
# Edit files
git commit -a -m "Fix security hole"

# Begin an interactive rebasing session
git checkout new-feature
git rebase -i master

마지막 명령으로 편집기가 열립니다 분기 new-feature에서 열린 2 개의 커밋을 관련 정보와 함께 표시됩니다.

pick 32618c4 Start developing a feature
pick 62eed47 Fix something from the previous commit

또한, 각각의 커밋 앞에있는 pick 명령은로 Rebase의 동작을 지정하는 임의의 명령으로 변경할 수 있습니다. 여기에서는 squash 명령을 사용하여 2 개의 커밋을 결합 할 수 있습니다 :

pick 32618c4 Start developing a feature
squash 62eed47 Fix something from the previous commit

저장하고 편집기를 닫으면로 Rebase가 시작됩니다. 이 때 다른 편집기 창이 결합 된 스냅 샷에 대한 커밋 메시지를 입력해야합니다. 커밋 메시지를 입력하면로 Rebase가 완료되고 git log 명령을 사용하여 커밋이 결합 된 것을 확인 할 수 있습니다. 이상의 조작을 시각화하면 다음과 같습니다 :

Git 튜토리얼 : git rebase -i 사용 예

여기에서 결합 된 커밋은 원래 커밋 중과도 다른 ID를 사용하는 것, 즉이 커밋은 사실 새로운 커밋임을 명심하십시오.

마지막으로, 앞으로 병합을 실행하여 정리 한 기능 가지를 master 브랜치로 통합합니다 :

git checkout master
git merge new-feature

인터랙티브로 Rebase의 위력은 재 작성된 master 브랜치의 기록에 나타납니다. ID가 62eed47 커밋은 불필요하게 기록에서 완전히 자취를 감추고 있습니다. 사정을 모르는 사람에게는 new-feature 개발자가 유능 최소한의 노력을 한번씩 실행 한 것만으로 개발을 완료 할 것처럼 보입니다. 이처럼로 Rebase는 프로젝트 기록을 정리하고 알기 쉽게하는 기능입니다.

1.6.4 - Git | Git의 기록 갱신 | git reflog

git reflog 명령

Git에서는 reflog라는 기능이 작동 분기 끝의 업데이트를 추적 할 수 있습니다. 그러면 어떠한 지점에서도 어떠한 태그도 참조되지 않은 업데이트 내용도 그 시점으로 돌아갈 수 있습니다. 기록을 갱신 한 후에는 심지어 reflog는 지점의 과거 상태가 기록되어 있으며, 필요한 경우에는 거기에 돌아갈 수 있습니다.

사용법

git reflog

로컬 저장소의 reflog를 표시하는 명령입니다.

git reflog --relative-date

상대 날짜 형식 (예 : 2 주 전)에서 reflog를 표시하는 명령입니다.

보충 설명

현재 HEAD에서 업데이트 (지점 전환, 새롭게 변경된 내용의 차와 기록 갱신 아니면 그냥 새 커밋의 실행 등)이 추가 될 때마다 reflog에 새로운 항목이 추가됩니다.

사용 예

git reflog 의 이해를 돕기 위해 하나의 예를 살펴 보자.

0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2

위의 reflog는 먼저 master에서 “2.2"라는 이름의 브랜치에 체크 아웃이 만들어진 다음 master 다시 있습니다. 그래서 hard 플래그를 지정한 취소하고 오래된 커밋으로 이동하고 있습니다. reflog는 가장 새로운 로그가 위에 표시되고 HEAD @ {0} 라는 레이블이 부여됩니다.

취소가 의도하지 않은 것이었다하더라도 2 개의 커밋을 취소하기 전에 (0254ea7)을 점하고 있던 커밋의 원래 정보가 reflog에 남아 있습니다.

git reset --hard 0254ea7

따라서, git reset 명령을 사용하여 master를 과거에 존재 한 커밋 취소 할 수 있습니다. 여기에는 기록 오 다시에 대한 안전망의 역할이 있습니다.

또한 변경이 로컬 저장소에 커밋 된 경우는 reflog가 유일한 안전망임을 또한 reflog는 HEAD의 이동을 기록하고있을뿐임을 명심하십시오.

1.7 - Git | 원격 Git 저장소

S VN의 경우는 하나의 중앙 저장소를 개발자 간의 커뮤니케이션 허브로 사용하고 협업은 개발자의 작업 복사본과 중앙 저장소간에 변경을 전달하는 과정을 의미합니다. Git 협력 모델은 이와는 달리 개발자 각각에 저장소의 복사본이 로컬 내역 및 분기 구조를 완전한 형태로 보유하고 있습니다. 개발자들은 다른 개발자와 개별 변경을 공유 할 필요가 없으며 일반적으로 일련의 노력을 함께 공유합니다. 중앙 저장소를 변경하는 경우 Git은 작업 복사본의 개별 변경 사항을 중앙 저장소에 커밋하는 것이 아니라 전체 분기를 저장소간에 공유합니다.

아래에 표시된 명령을 사용하여 다른 저장소와의 연결을 관리하고 다른 저장소에 지점을 푸시하여 그것을 공개하고 브랜치를 로컬 저장소에 끌어함으로써 다른 개발자 진행 상황을 확인 할 수 있습니다.

1.7.1 - Git | 원격 Git 저장소 | git remote

git remote 명령어

git remote 은 다른 저장소와 연결 작성, 내용 확인, 삭제하는 명령입니다. 원격 연결은 다른 저장소에 대한 직접 링크가 아닌 북마크 같다. 다른 저장소에 실시간 액세스를 할 것이 아니라, 비 단축 URL에 대한 참조로 사용할 수있는 단축 명칭으로 작동합니다.

예를 들어 다음 그림은 로컬 저장소와 중앙 저장소 사이 및 로컬 저장소와 다른 개발자의 저장소 사이의 2 개의 원격 연결을 보여줍니다. 그들을 전체 URL을 사용하여 참조하는 것이 아니라 다른 Git 명령에 “origin"및 “john"이라는 명칭의 바로 가기를 전달할 수있게합니다.

Git 튜토리얼 : git remote

사용법

git remote

다른 저장소에 원격 연결을 나열하는 명령입니다.

git remote -v

위의 명령과 비슷하지만 그러나 각 연결의 URL이 표시됩니다.

git remote add <name> <url>

리모트 저장소에 대한 새 연결을 만드는 명령입니다. 작성되면 다른 Git 명령에서 <url> 대신 <name>을 단축 단축키로 사용할 수 있습니다.

git remote rm <name>

<name> 라는 이름의 원격 리포지토리에 대한 연결을 제거하는 명령입니다.

git remote rename <old-name> <new-name>

원격 접속을 <old-name>에서 <new-name>이름 바꾸기 명령입니다.

보충 설명

Git은 각 개발자에 대해 독립적 인 개발 환경을 제공하도록 설계되어 있습니다. 따라서 저장소간에 정보가 자동으로 이동할 수 없습니다. 개발자는 수작업으로 중앙 저장소의 커밋을 로컬 저장소에 끌어하거나 수동으로 로컬 커밋을 추진함으로써 중앙 저장소로 복원 할 필요가 있습니다. git remote 그런 “공유 작업"명령에 URL을 넘겨 간편한 방법을 제공하는 명령입니다.

origin 원격 저장소

git clone 명령을 사용하여 저장소를 Clone하면 복제 된 저장소를 포인트 백하는 origin이라는 이름의 원격 연결이 자동으로 생성됩니다. 이 명령은 상류에서 변경을 풀거나 로컬 커밋을 공개 할 간편한 방법을 제공하는 것이며, 개발자는 중앙 저장소의 작업 복사본을 만들 때 유용한 명령입니다. 이 기능은 Git 기반의 대부분의 프로젝트에서는 중앙 저장소의 명칭이 origin되어 있습니다.

저장소 URL

Git은 원격 저장소를 참조하는 많은 수단을 지원하고 있습니다. 즉, 원격 저장소에 액세스하는 매우 간편한 방법으로 HTTP 프로토콜과 SSL 프로토콜이 준비되어 있습니다. HTTP는 저장소에 익명의 읽기 전용 액세스를 할 간단한 방법입니다. 다음은 그 예입니다 :

http://host/path/to/repo.git

그러나 일반적으로 HTTP 주소를 푸시 할 수 없습니다 (다른 개발자 로컬 저장소에 익명의 압박이 있더라도 항상 거부하는 것입니다). 리드 라이트 액세스하는 경우 SSH를 사용해야합니다 :

ssh://user@host/path/to/repo.git

이 경우 호스트 머신에서 유효한 SSH 계정이 필요하지만, 그것을 제외하면 Git은 기본적으로 인증을 필요로하는 액세스를 지원합니다.

사용 예

origin 이외에 다른 개발자의 저장소에 대한 연결을 만들어두면 편리한 경우가 많습니다. 예를 들어, 동료 John이 공개 저장소를 dev.example.com/john.git 에 보유하고있는 경우 다음과 같이 연결을 새로 만듭니다.

git remote add john http://dev.example.com/john.git

개별 개발자의 저장소에 대한 이러한 접근하여 중앙 저장소를 통하지 않고 협업이 가능합니다. 이 기능은 특히 대규모 프로젝트에서 작업하는 소규모 팀의 경우에 유용합니다.

1.7.2 - Git | 원격 Git 저장소 | git fetch

git fetch 명령어

git fetch 는 원격 저장소에서 로컬 저장소에 지점을 가져올 명령입니다. 가져온 브랜치는 지금까지 학습 해 온 일반 로컬 브랜치가 아니라 원격 브랜치로 저장됩니다. 이 기능은 그들을 로컬 저장소에 통합하기 전에 변경 내용을 확인할 수 있습니다.

사용법

git fetch <remote>

저장소에서 모든 분기를 가져 오는 명령입니다. 이 명령을 실행하면 관련된 모든 커밋 및 파일도 그 저장소에서 다운로드됩니다.

git fetch <remote> <branch>

위의 명령과 동일한 기능을 갖는 명령이지만, 그러나 페치하는 대상은 지정된 지점뿐입니다.

보충 설명

페치는 다른 개발자의 작업 내용을 확인하는 경우에 수행 할 작업입니다. 가져온 브랜치는 원격 브랜치로 표현되기 때문에 로컬 개발 작업에 전혀 아무런 영향을주지 않습니다. 인출 한 지점을 로컬 저장소에 통합하기 전에 그 내용을 확인하는 것이 가능하며, 따라서 인출은 안전한 작업 할 수 있습니다. 이 명령은 중앙 저장소의 진행 상황을 확인할 수 있다는 의미에서 SVN의 svn update 명령과 비슷하지만, 그러나이 명령은 실제로 지점의 로컬 저장소에 통합하지 않습니다.

원격 지사

원격 브랜치는 로컬 브랜치와 비슷하지만, 그러나 다른 개발자의 저장소의 브랜치를 가리키는 것입니다. 로컬 브랜치 마찬가지로 원격 브랜치를 체크 아웃 할 수 있지만, 이렇게하면 (로컬 저장소에서 과거의 커밋을 체크 아웃 한 경우와 유사한) detached HEAD 상태입니다. 즉, 원격 지사는 읽기 전용 지점이라고 생각할 수 있습니다. 원격 브랜치의 목록을 표시하려면 -r 플래그를 지정하여 git branch 명령을 실행합니다. 원격 브랜치의 시작은 그 지점이있는 원격 연결의 명칭이 부가되므로 로컬 브랜치와 혼동하는 것은 아닙니다. 예를 들어 다음의 짧은 코드는 origin 원격 저장소에서 가져 오기를 수행 할 때 나타나는 목록입니다 :

git branch -r
# origin/master
# origin/develop
# origin/some-feature

여기서도 또한 일반 git checkout 명령과 git log 명령을 사용하여 브랜치를 확인 할 수 있습니다. 원격 브랜치에 포함 된 변경이 승인 가능한 내용 일 경우 일반 git merge 명령을 사용하여 그것을 로컬 저장소에 병합 할 수 있습니다. 따라서, SVN과 달리 로컬 저장소를 원격 저장소와 동기화하는 작업은 실제로 인출 및 병합의 두 단계 작업입니다. git pull 명령은이 두 단계 작업을 간편화하기 위해 마련된 바로 가기입니다.

사용 예

이 예에서는 로컬 저장소를 중앙 저장소의 master 브랜치와 동기화 할 때의 일반적인 워크 플로우를 보여줍니다.

git fetch origin

이 명령을 실행하면 다운로드 된 지점이 표시됩니다 :

a1e8fb5..45e66a4 master -> origin/master
a1e8fb5..9e8ab1c develop -> origin/develop
* [new branch] some-feature -> origin/some-feature

아래 그림과 같이 이러한 원격 브랜치에있는 커밋은 원형이 아닌 사각형으로 표시되어 있습니다. 볼 수 있듯이, git fetch 명령을 실행하면 원격 저장소의 브랜치 전체에 액세스 할 수 있습니다.

Git 튜토리얼 : git fetch 중앙 저장소의 master에 추가 한 커밋을 검사하려면 다음 명령처럼 master 브랜치를 대상으로 git log 명령을 실행합니다 :

git log --oneline master..origin/master

다음 명령은 변경을 승인하고 그들을 로컬 master 브랜치에 병합합니다 :

git checkout master
git log origin/master

그리고 git merge origin / master 를 사용할 수 있습니다.

git merge origin/master

이제 origin / master 및 master 두 브랜치가 동일한 완결을 점하게 중앙 저장소와 동기화가 완료되었습니다.

1.7.3 - Git | 원격 Git 저장소 | git pull

git pull 명령어

중앙 저장소에서 변경의 로컬 저장소에 병합은 Git 기반의 협업 워크 플로우에서 잘 이루어지는 작업입니다. git fetch 명령과 연속 git merge 명령을 사용하여이 작업을 수행하는 방법은 이미 설명했지만, git pull 은이 두 명령을 소집 명령입니다.

사용법

git pull <remote>

현재 브랜치의 지정된 원격에서 복사를 페치하고 그것을 현재 브랜치에 즉시 병합합니다. 이것은 git fetch <remote> 명령을 실행 한 다음 git merge origin / <current-branch> 명령을 실행하는 것과 같습니다.

git pull --rebase <remote>

위의 명령과 비슷하지만 원격 브랜치를 현재 브랜치에 병합 할 때 git rebase 명령을 사용합니다.

보충 설명

git pull 명령은 SVN의 svn update 명령에 해당한다고 생각할 수 있습니다. 이 명령은 로컬 저장소를 중앙 저장소와 동기화하는 간편한 방법입니다. 다음 그림은 풀을 실행했을 때의 각 단계를 설명하는 것입니다.

Git 튜토리얼 : git pull

처음에는 로컬 저장소를 origin와 동기화되는 상태였다지만, git fetch 명령을 실행 한 결과 origin의 master 에 마지막으로 확인한 시점에서 진행이 있었던 것으로 밝혀졌습니다. 여기에서 git merge 명령을 실행하면 remote master 가 로컬 master로 병합됩니다.

로 Rebase 이용한 풀

–rebase 플래그는 기록 선형성을 확보하고 병합 커밋을 줄일 경우에 사용합니다. 로 Rebase는 “내 변경 작업은 모두 변경을 완료 한 것을 기반으로하고 싶다"고 말하는 동일한 것이며, 많은 개발자는 병합보다로 Rebase 선택하는 경향이 있습니다. 이러한 의미에서, 단순히 git pull 명령보다 –rebase 플래그를 지정하여 git pull 명령을 실행하는 것이, SVN의 svn update 명령에 가깝다고 할 수 있습니다.

실제로 –rebase 플래그를 지정한 풀 작업은 매우 일반적인 워크 플로가 있기 때문에 그것을위한 전용 설정 명령이 포함되어 있습니다 :

git config --global branch.autosetuprebase always

이 명령을 실행하면 이후의 모든 git pull 명령은 통합시 git merge 대신 git rebase 를 사용합니다.

사용 예

다음은 중앙 저장소의 master 브랜치 와의 동기화 방법을 보여줍니다 :

git checkout master
git pull --rebase origin

이 명령을 실행하면 다른 개발자의 작업 성과가 모두 반영된 것 위에 로컬 변경 될 수 있습니다.

1.7.4 - Git | 원격 Git 저장소 | git push

git push 명령

푸시는 브랜치를 로컬 저장소에서 원격 저장소에 쓰기 작업을 의미합니다. 이 명령은 git fetch 반대되는 것이지만, 페치는 지점을 로컬 저장소로 가져 오는 작업 인 반면, 푸시 지점을 원격 저장소로 내보내기 작업입니다. 이 명령은 변경의 잘못 쓰기를 일으킬 수 있으므로 사용시주의가 필요합니다. 이 문제는 아래에서 설명합니다.

사용법

git push <remote> <branch>

관련된 모든 커밋 및 내부 개체와 함께 지정된 지점을 <remote>에 밀어 명령입니다. 이 명령을 실행하면 푸시 대상 리포지토리에 로컬 브랜치가 생성됩니다. 변경의 잘못 쓰기를 방지하기 위해 Git은 푸시 연락처 저장소에서 통합 처리가 앞으로 병합 아닌 경우는 푸시가 거부됩니다.

git push <remote> --force

위의 명령과 비슷하지만 앞으로 병합 아닌 경우에도 강제로 밀어가 실행됩니다. 푸시 조작에 의해 어떻게 될지를 완벽하게 이해하고있는 경우를 제외하고는 –force 플래그를 사용하여 수 없습니다.

git push <remote> --all

모든 로컬 브랜치를 지정하여 원격 저장소에 밀어 명령입니다.

git push <remote> --tags

브랜치를 푸시하는 것만으로는 예 –all 플래그가 지정된 경우에도 태그가 자동으로 푸시되지 않습니다. –tags 플래그를 지정하면 모든 로컬 태그를 원격 저장소에 보낼 수 있습니다.

보충 설명

git push 의 가장 일반적인 사용 사례는 로컬 변경의 중앙 저장소에 게시합니다. 몇 번이나 로컬 커밋을 실행하고 그것을 다른 개발자와 공유 할 단계가 된 경우 (필요한 경우) 인터랙티브로 Rebase 사용하여 그것을 정리하고 그것을 중앙 저장소에 푸시 합니다.

Git 튜토리얼 : git push

위 그림은 로컬 master 가 중앙 저장소의 master 를 추월 해 진행하고 그 상태에서 git push origin master 명령을 실행하여 변경 사항을 게시하면 어떻게되는지를 보여줍니다. git push 가 원격 저장소에서 git merge master 명령을 실행하는 경우와 본질적으로 동등하다는 것을 명심하십시오.

강제 추진

Git은 푸시의 결과로 앞으로 병합 이외의 처리가 필요한 경우, 푸시 요청은 거부됩니다. 따라서, 원격 저장소와 로컬 저장소가 분기 상태에있는 경우에는 먼저 원격 브랜치를 가져 와서 로컬 브랜치로 병합 한 후 다시 밀어 시도해야합니다. 이것은 SVN에서 변경 내용을 커밋하기 전에 로컬 저장소를 원격 저장소로 동기화 할 때 svn update 명령을 사용하는 것과 비슷합니다.

–force 플래그를 지정하면이 제한이 해제되고 원격 저장소를 로컬 저장소에 일치시키기 위해 마지막으로 끌어 된 시점 이후에 원격 저장소에 변경이 발생했다면 그들은 모두 삭제됩니다. 강제 푸시가 필요한 유일한 경우는 공개한지 얼마 안된 커밋에 결함이 발견 git commit –amend 명령 또는 대화 형 리베이스를 사용하여 그것을 수정 한 경우입니다. 그러나이 경우에도 –force 플래그를 적용하기 전에 결함이있는 지점을 끌어 개발자는 한 명도 없다는 확신이 있어야합니다.

푸시 처는 베어 저장소 제한

또한, 푸시 시설은 –bare 플래그를 지정하여 만든 저장소에 한정해야합니다. 푸시는 원격 저장소의 구조를 변경하는 작업이기 때문에 다른 개발자의 저장소에 푸시는 결코 가서는 안됩니다. 베어 저장소에만 작업 디렉토리를 가지지 않기 때문에 다른 개발자의 개발 작업을 방해하는 것은 아닙니다.

사용 예

다음 예제는 로컬 작업 성과를 중앙 저장소에 공개하는 일반적인 방법을 보여줍니다. 먼저 로컬 master 를 확실히 최신의 것으로하기 위해 중앙 저장소의 master를 가져 와서 로컬 변경 게다가으로 업데이트합니다. 여기서 커밋을 공유하기 전에 대화 형 리 기반을 활용하여 커밋을 정리하면 좋을 것입니다. 다음은 git push 명령을 사용하여 로컬 master 의 모든 커밋을 중앙 저장소로 보냅니다.

git checkout master
git fetch origin master
git rebase -i origin/master
# Squash commits, fix up commit messages etc.
git push origin master

이미 로컬 master 가 최신으로되어 있는지 확인하고 있기 때문에 병합은 앞으로 병합 될 것이며, git push 명령을 실행해도 앞서 말한 앞으로 병합 이외의 통합 처리로 인한 문제 가 발생하지 않습니다.

2 - SVN

2.1 - SVN 형상관리

SVN이란?

Svn(Subversion)은 형상관리 도구로 프로그램 파일을 버전별로 관리할 수 있다.

checkout (co)

저장소(repository)에서 로컬 작업공간으로 소스를 받아온다.

사용법

svn checkout [SVNURL] [체크아웃할대상]

예시

$ svn checkout https://desktop-8kkel5e/svn/kimkc/
Checked out revision 0.

add

SVN에 관리할 파일이나 디렉토리를 추가한다. 추가 후에는 commit을 해줘야 저장소에 반영 된다.

사용법

svn add [추가할 파일명]

예시

$ svn add Test.java
A         Test.java
$ svn commit
adding Test.java

commit (ci)

로컬에서 수정된 내용을 저장소에 적용시킨다.

사용법

svn commit [커밋할파일명] -m [로그로 남길 메세지]

예시

$ svn commit Test.java -m "test"
Adding         Test.java
Transmitting file data .done
Committing transaction...
Committed revision 1.

update (up)

저장소(repository)의 최신 내용으로 로컬 소스를 갱신 한다.

사용법

svn update

예시

$ svn update
Updating '.':
At revision 3.

delete(del, remove, rm)

SVN에 관리할 파일이나 디렉토리을 삭제한다. 삭제 후에는 commit을 해줘야 저장소에 반영 된다.

사용법

$ svn delete [SVN관리목록에서 삭제할 파일명]

예시

$ svn delete text.txt
D        text.txt
$ svn commit
Deleting test2.c

svn 변경된 파일 상태 확인

사용법

svn status

repository url 확인

사용법

$ svn info
Path: .
Working Copy Root Path: D:\svn-file-test\kimkc
URL: https://desktop-8kkel5e/svn/kimkc
Relative URL: ^/
Repository Root: https://desktop-8kkel5e/svn/kimkc
Repository UUID: 08d25a28-c52d-f14b-9aa0-5c24a007a8d5
Revision: 0
Node Kind: directory
Schedule: normal
Last Changed Rev: 0
Last Changed Date: 2019-07-30 09:50:14 +0900 (화, 30 7 2019)

log

Repository에 파일 수정 이력 조회한다.

사용법

$ svn log [PATH]

더 자세히 보려면

$ svn log -v
$ svn log
------------------------------------------------------------------------
r3 | kimkc | 2019-07-30 13:52:22 +0900 (화, 30 7 2019) | 1 line

test3
------------------------------------------------------------------------
r2 | kimkc | 2019-07-30 11:14:30 +0900 (화, 30 7 2019) | 1 line

test2
------------------------------------------------------------------------
r1 | kimkc | 2019-07-30 10:00:24 +0900 (화, 30 7 2019) | 1 line

test
------------------------------------------------------------------------
$ svn log -r 30:100 test.c

리비전 번호 30~100 내에서 test.c에 대한 로그를 출력한다.

blame

각 라인을 수정한 사람이 누구인지 확인한다.

예시

$ svn blame sample.c

export

저장소에서 원본 파일만 받아 온다.

사용법

svn export  [SVNURL]  [저장될 장소]

예시

$ svn export  http://svn.bds.fbwotjq.com/www/manager/trunk/ docs_manager

해당 리비젼 소스만 expert

export는 버전관리를 위한 부속 파일들은 제외하고 순수한 소스만 받아오기 때문에, 주로 source release 용도로 사용되게된다. -r 옵션을 지정해서 해당 리비젼의 소스를 받아올 수 있다.

사용법

svn export [SVNURL] [저장폴더] -r [리비젼 번호]

예시

svn export  https://desktop-8kkel5e/svn/www/manager/trunk/ docs_manager -r 186 

import

사용법

svn import [올릴대상] [SVNURL] -m [로그로 남길 메세지]

예시

$ svn import docs_js https://desktop-8kkel5e/svn/www/manager/trunk/ -m "svn import test"

info

현재 연결된 SVN 파일 저장소의 정보를 조회한다.

$ svn info

예제

$ svn info
Working Copy Root path : /home/
URL : http://192.168.0.1/project
Relative URL : ...

update

현재 파일 저장소에 저장된 최신 변경 사항을 받는다.

사용법

svn update

예제

$ svn update
Updation '. :
At revision 1111.

diff

수정된 파일 내용을 비교해 준다.

사용법

svn diff --revision [위에 log에서 확인한 r숫자에서 숫자 부분만] [비교할 파일명]

예제

$ svn diff --revision 1111 test.c
===================================
--- //test log
+++//new log
....

relocate

저장소 URL이 변경되었을 때, 로컬에서 URL을 변경해 준다.

사용법

SVN 1.6 이하

svn switch --relocate {이전 URL} {변경 URL}

SVN 1.6 이상

svn relocate {변경 URL}
$ svn relocate https://svn.devkuma.com/svn/kimkc

svn 현재 버젼 체크

$ svn --version

참조

3 - IntelliJ 퀵 가이드

IntelliJ IDEA 단축키 목록

단축키 설명
Command + Option + L 소스 코드 들여쓰기나 탭 등을 이쁘게 정렬해 준다.
Command + delete 커서가 위한 한줄를 삭제한다.
Command + D 커서가 위한 한줄를 복사한다.
Command + B 커서가 올라온 소스 파일로 이동한다.
Command + Option + B Java의 인터페이스 메소드에 커서가 올려져 있을 때 구현된 소스로 이동한다. 혹은 “우클릭 > Go to > Implementation” 이렇게 가능하다.
Control + Option + O 사용하지 않는 import 삭제한다.
Command + Shift + U 대소문자 변경한다.
Command + Shift + 8 멀티 커서를 켜고 끈다. 이는 여러줄을 한번에 수정할때 유용하다.

Intellij properties 파일을 한글로 보기

Eclipse의 경우에는 properties를 다국어를 보기 위해서는 Properties 플러그인을 따로 설치를 해야 했다. 이에 반해 IntelliJ IDEA에서는 간단한 설정을 통해서 다국을 볼 수 있다.

  • [Preferences]-[Editor]-[File Encodings]에 들어간다.
  • Transparent native-to-ascii conversion를 체크한다.
    • Apply 버튼을 눌려서 적용한다.

Intellij Java import 자동 등록

Intellij에서 자동으록 import 를 등록해 주도룩 설정하는 방법에 대해서 알아보자.

  • [Preferences]-[Editor]-[General]-[Auto import]에 들어간다.
  • Add unambiguous imports on the fly를 체크한다.
  • Apply 버튼을 눌려서 적용한다.

Intellij 사용하지 않는 Java import 자동 삭제

Intellij에서 자동으로 사용하지 않는 Java import 제거해 주도록 설정하는 방법에 대해서 알아보자.

  • [Preferences]-[Editor]-[General]-[Auto import]에 들어간다.
  • Optimaize import on the fly를 체크한다.
  • Apply 버튼을 눌려서 적용한다.

Intellij에서 컴파일 오류가 없어지지 않을 때

Intellij에서 Import 하지 못해서 다른 클래스를 찾을 수 없는 컴파일 오류가 발생하는 경우가 있다.

  • [File]-[Invlidate Caches]을 클릭한다.
  • Invalidate and Restart을 클릭한다.

Intellij 프로젝트 자바 버전 설정

JDK 설정

  • [File ]-[Project Structure]-[Project]을 클릭한다.
  • Project SDK에서 자바 버전으로 설정한다.

Gradle JRE 설정

  • [Preference]-[Build, Execution, Deployment]-[Build Tools]-[Gradle]을 클릭한다.
  • “Build and run"에서 JRE를 자바 버전으로 설정한다.

DataGrip 단축키

단축키 설명
Command + Shift + U 대문자 변환
Command + Option + L SQL 코드 들여쓰기나 탭 등을 이쁘게 정렬해 준다.