로컬저장소에서의 Git
- 로컬 환경(홀로 작업하는)에서의 Git 사용법과 개념이다.
* 전체 Git 명령어 (URL)
Commit
ⓥ 저지르다, 위임하다
- 프로젝트에서 의미를 갖는 최소 단위이다.
- "새로고침"과 유사한 기능이며, 업데이트를 확정짓는 기능이다.
* 커밋을 하기에 적절한 시기
1. 일정 시간이 지난 후
2. 함수의 생성 및 수정사항이 생겼을 때
-
관련 명령어
git commit
: 커밋을 시도, 커밋 메세지를 작성하는 화면이 나오게 된다.
- 별다른 설정을 하지 않았다면, vim으로 커밋 메세지를 작성하게 된다.
- 해당 커밋을 설명하는 메세지를 작성하는 것이 일반적이다.
git commit -a
: 변경된 저장소 파일 모두를 커밋하는 명령어이다.
- "-a" 옵션은 "all"을 의미한다.
git commit -m "커밋 메시지"
: git commit 명령을 실행한 후 vim 에디터를 통해 커밋 메시지를 작성하는 것이 아닌,
"커밋 메시지"를 명령어와 함께 입력하여 메시지를 바로 작성하게 하는 명령어이다.
- 이와 같이 메시지를 명령과 함께 입력하는 것을 Inline method 라고 한다.
* GitHub 상에서의 Commit
Commit changes 항목의 옵션
Update 파일이름
- '파일이름'의 수정 내역을 남길 커밋 메시지를 입력한다.
- 커맨드 라인에서 커밋 메시지를 입력할 때의 첫 번째 행에 해당된다.
Add an optional extended description
- 자세한 설명을 남겨야 할 경우 추가로 커밋과 관련된 설명을 입력한다.
- 커맨드 라인에서 커밋 메시지를 입력할 때의 두 번째 이후 행에 들어가는 내용이다.
Commit directly to the master branch
- master 브랜치에 바로 커밋할 때 선택하는 옵션이다.
Create a new branch for this commit and start a pull request
- 풀 리퀘스트를 위한 새로운 브랜치를 생성할 때 선택하는 옵션이다.
Branch
ⓥ 가지가 퍼지다, 분기하다
- VCS에서 서로 영향을 받지 않는 작업 단위이다.
- 각각의 클라이언트가 작업하는 하나의 Branch는 Merge 이전까지는 다른 Branch 와 독립적이다. (영향을 받지 않는다.)
-
관련 명령어
git branch
: 현재 존재하는 브랜치를 조회한다.
- 브랜치명 앞에 ' * (asterisk) ' 표시는 지금 작업 중인 브랜치임을 의미한다.
git branch 브랜치명
: '브랜치명' 에 해당하는 브랜치를 생성한다.
- 브랜치를 생성한 것이지, 생성한 브랜치로 이동한 것은 아니다.checkout -b git checkout -b sdf
git checkout -b gitcheckout -b
git checkout -b 브랜치명
: "브랜치명" 에 해당하는 브랜치를 생성하고, 생성한 브랜치로의 checkout 까지 한 번에 진행하는 명령이다.
- git branch + git checkout
git branch -a
: 현재 저장소에 존재하는 Branch들을 출력한다.
Merge
ⓥ 합병하다, 합치다
- 한 브랜치에 다른 브랜치의 작업 내용을 흡수(반영)한다.
- merge 이후에도 A 브랜치와 B 브랜치는 독립적으로 존재한다. (피합병 브랜치가 사라지는 것이 아니다.)
* master 브랜치와의 merge의 경우, 두 가지 issue가 있을 수 있다.
I. master 브랜치에 위치한 상황에서 B 브랜치를 merge 하는 경우
- master 브랜치에 B 브랜치의 내용이 합쳐진다.
II. B 브랜치에 위치한 상황에서 master 브랜치를 merge 하는 경우
- B 브랜치에 master 브랜치의 내용이 합쳐지고, master 브랜치의 내용은 변경되지 않는다.
-
관련 명령어
git merge 브랜치명
: 현재 작업중인 브랜치에 '브랜치명' 브랜치를 끌어와 병합시킨다.
* git merge 명령을 입력하고, [Space Bar] 키를 눌러 한 칸을 띄어쓴 후 [Tab] 키를 누르면 어떤 브랜치들이 병합 대상인지를 확인할 수 있다.
Ignore
ⓥ 무시하다
- 저장할 필요가 없는 파일들을 적절하게 무시하기 위한 기능이다.
- .ignore 파일에 프로젝트 작업 시에 생기는 불필요한 파일들에 저장하여 적절히 무시한다.
- .ignore 파일에 일련의 파일 목록과 파일을 구분할 수 있는 패턴의 내용등이 기입된다.
* gitignore 참고자료 (URL)
* gitignore.io (URL)
- .ignore 파일을 사용자의 OS와 IDE, 프로그래밍 언어에 맞춰서 자동으로 생성해주는 Web Application이다.
- 앱을 통해 생성된 ignore 파일 내용을 복사해서 "touch" 명령어를 통해 만든 ignore 파일에 붙여넣기 하는 방식이 권장된다.
- 이후 ignore 파일을 commit 하면 작업이 완료된다.
-
관련 명령어 (UNIX / Linux)
touch .파일명
: 빈 파일을 생성하는 UNIX 명령어이며, 본래는 파일의 타임스탬프를 변경시키는 용도로 사용되곤 했다.
- ignore 파일을 생성하는데 요긴하게 사용하는 명령어이다.
ex) touch .gitignore
is -a
: "." (dot) 로 시작하는 파일까지 출력시키는 명령어이다.
- "is" 명령어는 "." (dot) 로 시작하는 파일은 출력시키지 않는다.
is -al
: "." (dot) 로 시작하는 파일까지 출력시키며 동시에 파일의 타임 스탬프 값까지 출력시키는 명령어이다.
- "is" 명령어는 "." (dot) 로 시작하는 파일은 출력시키지 않는다.
※ gitignore 참고자료 URL
Conflict
ⓝ 충돌, 논쟁
- 두 개의 브랜치에서 동시에 같은 파일의 같은 곳을 수정하고, 그것을 병합시킬 때 생기는 충돌에 관한 문제이다.
-
Conflict 발생 예시 (Git Bash)
1. Conflict 발생 인지
user@user-pc MINGW64 ~
$ mkdir example
// 예시 용도의 example 디렉토리(폴더) 생성
user@user-pc MINGW64 ~
$ cd example
// example 디렉토리로 이동
user@user-pc MINGW64 ~/example
$ git init
Initialized empty Git repository in C:/Users/user/example/.git/
// example 디렉토리를 git repository 로 초기화
user@user-pc MINGW64 ~/example (master)
$ vim example.cpp
// 예시 용도의 C++ 파일(example.cpp) 작성
user@user-pc MINGW64 ~/example (master)
$ cat example.cpp
#include <iostream>
int main(){
int a, b;
}
// example.cpp 파일의 내용
user@user-pc MINGW64 ~/example (master)
$ git add example.cpp
// example.cpp 를 git이 추적하도록 명령
user@user-pc MINGW64 ~/example (master)
$ git commit
[master (root-commit) 05c9a43] First Commit // 커밋 메세지
1 file changed, 5 insertions(+)
create mode 100644 example.cpp
// 1차 커밋
user@user-pc MINGW64 ~/example (master)
$ git branch Hotfix
// "Hotfix" 브랜치 생성
user@user-pc MINGW64 ~/example (master)
$ git checkout Hotfix
Switched to branch 'Hotfix'
// "Hotfix" 브랜치로 체크아웃(이동)
user@user-pc MINGW64 ~/example (Hotfix)
$ vim example.cpp
// "Hotfix" 브랜치에서의 example.cpp 수정
user@user-pc MINGW64 ~/example (Hotfix)
$ cat example.cpp
#include <iostream>
int main(){
int a, b;
cin >> b;
}
// "Hotfix" 브랜치에서의 example.cpp 수정내용
user@user-pc MINGW64 ~/example (Hotfix)
$ git add example.cpp
user@user-pc MINGW64 ~/example (Hotfix)
$ git commit
[Hotfix 3aa55af] Second Commit
1 file changed, 1 insertion(+)
// 커밋
user@user-pc MINGW64 ~/example (Hotfix)
$ git checkout master
Switched to branch 'master'
// 다시 "master" 브랜치로 체크아웃(이동)
user@user-pc MINGW64 ~/example (master)
$ cat example.cpp
#include <iostream>
int main(){
int a, b;
}
// 보다시피 "master" 브랜치에는 "Hotfix" 브랜치의 수정사항이 반영되지 않았음
user@user-pc MINGW64 ~/example (master)
$ vim example.cpp
// "master" 브랜치에서의 수정 시작
user@user-pc MINGW64 ~/example (master)
$ cat example.cpp
#include <iostream>
int main(){
int a, b;
cin >> a; // "Hotfix" 브랜치에서의 내용과 다름!
}
// "master" 브랜치에서의 example.cpp 수정내용
user@user-pc MINGW64 ~/example (master)
$ git add example.cpp
user@user-pc MINGW64 ~/example (master)
$ git commit
[master 198a3a3] Third Commit
1 file changed, 1 insertion(+)
// 커밋
user@user-pc MINGW64 ~/example (master)
$ git merge Hotfix
Auto-merging example.cpp
CONFLICT (content): Merge conflict in example.cpp
Automatic merge failed; fix conflicts and then commit the result.
// "master"브랜치에서 "Hotfix"브랜치를 대상으로 한 merge를 시도
// 그러나, Conflict 발생
user@user-pc MINGW64 ~/example (master|MERGING)
$ cat example.cpp
#include <iostream>
int main(){
int a, b;
<<<<<<< HEAD // Conflict 가 발생한 부분의 시작 "HEAD"
cin >> a;
======= // 각각의 Conflict 에 해당되는 내용이 어디에 속하는지를 구분해주는 선
cin >> b;
>>>>>>> Hotfix // Conflict 가 발생한 부분의 끝 "해당 브랜치명"
}
// Conflict 가 발생한 example.cpp 파일의 내용
// merge 중 발생한 Conflict가 해결하는 도중이라는 명시적인 표시 "(master|MERGING)"
2. Conflict 해결
user@user-pc MINGW64 ~/example (master|MERGING)
$ vi example.cpp
// Conflict 가 발생한 example.cpp 파일 수정 시작
user@user-pc MINGW64 ~/example (master|MERGING)
$ cat example.cpp
#include <iostream>
int main(){
int a, b;
cin >> a;
cin >> b;
}
// example.cpp 파일의 수정 내용
// Conflict에 해당되는 두 구문을 합치는 방식으로 해결함
user@user-pc MINGW64 ~/example (master|MERGING)
$ git commit -a
[master c77dc8d] Merge branch 'Hotfix'
// 커밋
user@user-pc MINGW64 ~/example (master)
// Conflict 가 해결됨을 의미하는 "master" 브랜치 표시
$ cat example.cpp
#include <iostream>
int main(){
int a, b;
cin >> a;
cin >> b;
}
// Conflict 해결 결과
※ 충돌을 해결하기 위해서는 충돌이 발생한 부분이 어떤 의미인지 개발자가 이해하고 직접 해결해야 함
(Git은 Compiler가 아님에 유의하자!)
Log
ⓝ 기록, 일지
- Git에서 제공하는 커밋 내역을 확인할 수 있는 기능이다.
- 40글자의 SHA-a 체크섬 값, 커밋한 사용자, 커밋 시각, 커밋 메세지 등을 제공한다.
-
관련 명령어
git log -p
: 각 커밋에 적용된 실제 변경 내용을 보여준다.
git log --word-diff
: diff 명령의 실행 결과를 단어 단위로 보여준다.
git log --stat
: 각 커밋에서 수정된 파일의 통계 정보를 보여준다.
git log --name-only
: 커밋 정보 중, 수정된 파일의 목록만 보여준다.
git log --relative-date
: 정확한 시간이 아닌, 상대적인 시간(n일 전, n주 전)을 비교하는 형식으로 보여준다.
git log --graph
: 브랜치 분기와 병합 내역을 아스키 그래프로 보여준다.
Ex. Conflict 해결과정에서의 git log 명령어 사용 예시
git log -p
git log --word-diff
git log --stat
git log --name-only
git log --relative-date
git log --graph
* 녹색과 빨간색 세로 점선은 브랜치의 분기 내역을 보여주는 것임