Git을 이용하기 위해 먼저 저장소를 구분할 필요가 있다
저장소의 분류는 2가지로 나뉘는데 본인의 로컬 저장소(local repository), 사람들과 공유하는 원격 저장소(remote repository)로 나뉜다
이제, 본인 로컬에 Git 저장소를 만들어 보자
Git 저장소를 만드는 방법에는 또 2가지가 있다.
1. cd ~/Desktop // 바탕화면으로 이동
2. mkdir example // 폴더 생성
3. cd example // 폴더로 이동
4. git init // example 폴더를 저장소로 초기화
// 저장소로 등록을 하게 되면 폴더 안에 .git 폴더가 만들어져 저장소로 관리된다
위에 명령어로 본인 로컬의 저장소를 초기화하고 gitHub의 원격 저장소와 연동시켜줘야 한다.
git remote add origin https://github.com/pparkgi/pratice.git
touch test.md
or 에디터 툴로 직접 생성git add .
git commit -m "test"
git push -u origin master
위의 1번 방법보다 비교적 쉬운편이다
clone은 다른 프로젝트에 참여하거나 git 저장소를 복사하고 싶을 때 사용한다
git clone https://github.com/pparkgi/pratice.git 본인이 원하는 디렉토리명(option)
위와 같이 하면 되는데 본인이 생성한 디렉토리 경로에 가서 입력하면 뒤에 option을 빼면 되고 새로운 디렉터리에 git clone을 하고 싶으면 뒤에 디렉터리명을 붙여준다.
이제 git 사이클에 대해 이야기 해보도록 하자
본인이 코드를 수정하고 저장하는 작업공간을 이야기 한다.
Working directory에는 2가지가 존재한다
1. tracked(관리대상) - git add
에 포함된 파일, 파일을 tracked(추적)해서 저장이력을 체크한다.
2. untracked(비관리대상) - git add
에 포함되지 않은 파일 즉, tracked을 하지 않은 파일
tracked을 시작한 단계
stage aread도 2가지가 존재한다.
1. unmodified - git add
에 포함은 되었으나, 변경 되지 않은 상태
2. modified - git add
에 포함 및 변경 된 상태
git add
를 통해 tracked 된 파일의 저장이력을 저장하는 단계
처음에 git add
를 통해 파일을 tracked해도 수정사항이 있는 경우 마지막 지점에서 다시 git add
를 해줘야 마지막 수정사항을 tracked한다.
=> git add
는 되도록 마지막 수정사항이 있는 지점에서 하는 것이 좋아 보인다
index 단계에서 trakced 된 파일 저장이력에 git commit
을 통해 메세지를 담아 어떤 변경사항이 있는지 기록하고 로컬 저장소에 반영(저장)하는 단계
이 단계는 아직 원격 저장소에 연결 된 상태가 아니기에 마지막으로 git push
를 이용해 원격 저장소로 올려야 한다
local repository 단계에서 git push
를 통해 원격 저장소로 올리는 단계, 최종적으로 원격 저장소에 올림으로써 다른 팀원들과 branch 및 파일들을 공유할 수 있게 된다.
git status
: 파일의 상태의 변화를 알려주는 행위
git diff
: Unstaged 상태 파일의 변경이력을 확인
두 커밋간이나 HEAD와 워킹 디렉토리의 차이점을 보여주는 명령어
git diff --color-words
: 변경된 라인 대신 단어(공백을 구분자로)로 표시가 된다.
git diff --word-diff
: 변경 된 사항은 지워지고 추가된 단어를 좀 더 명시적으로 표시한다.
git diff HEAD
: 마지막 커밋과 현재 수정사항 확인
3-1. git diff HEAD HEAD^
: 마지막 커밋과 그 전 상황의 커밋 비교
git diff --cached 또는 git diff --staged
: 현재 stage 된 수정사항만 따로 확인
git log
: 저장소의 커밋 히스토리를 시간순으로 보여 줌
커밋 히스토리를 시간순으로 보여준다. 즉, 가장 최근의 커밋이 가장 먼저 나온다. 그리고 이어서 각 커밋의 SHA-1 체크섬, 저자 이름, 저자 이메일, 커밋한 날짜, 커밋 메시지를 보여준다.
git log --graph
: log 기록을 그래프처럼 표현
git log --oneline
: log 기록을 한 줄로 표현, git log --online --graph
같이 사용 가능
git log -p -[number]
: git diff
와 같은 기능이지만 동료들의 커밋을 빨리 보고 파악하기 편리함
number에다가 원하는 숫자를 기입하면 그 숫자만큼의 최근 기록을 보여준다
git log --stat
: 각 커밋의 어떤 파일이 수정되고 수정된 파일의 변경사항(줄 추가 및 삭제 사항)을 요약정보를 알려 줌
git add
: index 영역에 새로운 파일을 tracked 하거나 tracked 된 파일의 변경사항을 알리는 행위
git add tesd.md
: 특정 파일에 대한 변경 내역을 index 영역에 올림git add .
: 모든 변경 내역을 index 영역에 올림git 1.x ver
git 2.x ver
git commit
: git add 명령어는 git flow의 첫 단계에 해당되며 인덱스에 새로운 파일이 생겼다는 것을 알리는 행위이다. 이 상태는 저장소에는 반영이 되지 않은 상태이며 git commit 명령을 통해 비로소 저장소에 변경내역이 반영된다.
git commit -m "message"
: index에 등록된 파일의 변경 이력을 message와 함께 로컬 저장소에 올림git commit -am "message"
: a 옵션에 의해 git add
단계를 생략하고 모든 변경이력에 대한 커밋메세지 작성git commit -av
: 위와 같은 형식이지만 vim을 켜서 변경사항도 같이 확인하면서 메세지 등록 가능git checkout
: 다른 브랜치로 이동할 때 사용하는 명령어
git checkout -t [origin/원격branchname]
: 원격 브랜치를 로컬 저장소로 가져온다git checkout -b [branchname]
: 브랜치 생성과 동시에 해당 브랜치로 이동git checkout -- [filename]
: git add
전 상태에서 working directory에서 작업한 내용을 작업 전 상태로 되돌려 줌git reset
: Stage 영역을 초기화 시킴
git reset HEAD [filename]
: git add
이후에 상태를 되돌리고 싶을 때 하는 명령어, git add
전 단계로 돌아감, (코드는 그대로 남아 있음)
git reset --hard [HEAD or 특정commit지점]
: 위와 같이 git add
전 단계로 돌아가는데 변경 된 코드까지 완벽하게 되돌리게 해주는 명령어git push
: 로컬 저장소의 등록된 사항을 원격 저장소에 등록하는 행위
git push origin [branchname]
: git commit
을 통해 로컬에 저장 되어 있는 내용을 해당 브랜치를 [branchname]으로 원격 저장소에 올리는 행위
git push -u origin [branchname]
: 이 행위를 안 하면 git 위의 명령어 처럼 매번 git push origin [branchname]
해줘야 하지만 -u 옵션을 사용하면 push 때 이전 히스토리를 기억하기 때문에 추후에는 git push
만 해줘도 됨 (-u 옵션은 처음에 한 번만 실행)
git pull
: 원격 저장소의 등록된 사항을 로컬 저장소로 가져오는 행위, 다른 동료가 올린 branch는 원격 저장소에 push 되기 전까지는 접근할 수가 없음
git pull origin [원격branchname]
: 원격에 있는 브랜치를 현재 위치하는 브랜치에 가져와 merge까지 하는 작업git branch [branchname]
: 새로운 브랜치를 생성한다.
git branch --set-upstream-to=origin/[원격에 존재하는 branchname] [로컬에 존재하는 branchname]
: 협업 시 원격 저장소에 있는 branch 내용을 로컬에 반영하지 않았다면 원격 저장소에 있는 브랜치를 추적(연결) 한 후 git pull
을 통해 merge 한다
[로컬에 존재하는 branchname]을 생략하면 지금 현재 위치하는 브랜치에 원격 브랜치를 연결한다
git branch -a
: 로컬, 원격 브랜치 리스트 모두 조회
- 장점
commit 지점을 원하는 곳 마다 생성 함으로써 백업이나 실수를 방지 할 수 있다
단순한 매커니즘이기에 입문자들이 이해하기 쉽다
보통 하나의 기준을 가지는 브랜치(마스터 브랜치)를 공유해 feature 브랜치를 생성 해 각각 다른 브랜치에서 여러 사람들이 작업한다. 때문에 원래 브랜치의 커밋들은 변경되지 않고 계속 유지되어 다른 개발자들의 작업과 공유되는 것에 대해 신경쓸 필요가 없다- 단점
다른 브랜치에서 master로 merge를 하는 경우 master와 다른 브랜치가 merge되는 지점에 merge commit이 생겨 큰 프로젝트를 하는 경우 merge commit이 많아지게 됨으로 굉장히 지저분하게 보인다
- 장점
merge commit을 하나로 만들어 굉장히 깔끔해 보인다(직관적인 히스토리) => 커밋 히스토리가 굉장히 깔끔함- 단점
충돌상황을 단계별로 계속 해결해줘야 해서 -i옵션(--squash 역할)을 사용 시 굉장히 복잡하다
1. 예제 브랜치 생성 및 commit 여러개 생성
2. rebase 시작
3. rebase 기준 commit 및 -i옵션(squash) 할 커밋 설정
4. 커밋 메세지 정리하기
아래와 같이 여러개의 커밋 메세지를 정리해서 한 문장으로 표현한다
5. git push origin branchname
으로 push를 하고 원격 저장소에 올린다
6. github에서 PR을 날리고 merge를 시킨다
7. master branch에서 pull을 받아 rebase를 적용시킨다
1. 마스터 브랜치와 동일한 커밋 지점에서 피쳐 브랜치를 생성한 뒤 conflict를 발생 시키기 위해 다시 마스터 브랜치로 돌아와서 커밋을 발생 시킨다.
2. 예제를 위해 2번째 커밋을 발생시킨다.
3. 피쳐 브랜치로 돌아와 conflict 발생 유도를 위해 피쳐 브랜치 만에 커밋을 발생시킨다.
4. 예제를 위해 2번째 커밋을 발생시킨다.
5. 피쳐 브랜치에서 rebase를 시작한다 git rebase -i master
를 하고 기준점을 p로 squash를 할 커밋을 s로 설정한다.
6. 아래 사진 처럼 conflict가 발생한 내용을 보여준다. HEAD는 현재 마스터 브랜치 === 아래 내용은 rebase_point의 내용을 보여준다
7. 코드 내용을 본인의 의도대로 정리 해준다.
8. 코드를 수정해서 적용을 했으니 다음 단계 커밋을 계속 진행하기 위해 git add
=> git rebase --continue
를 실행 해 진행한다.
9. 두 번째 커밋을 본인의 의도대로 정리 해준 뒤 다시 한 번 git add
=> git rebase --continue
를 실행한다.
10. 마지막까지 conflict를 해결 했으면 아래와 같이 git push origin rebase_point
를 실해 해 github 원격 저장소에 올려 merge 준비를 한다.
11. github에서 merge 작업을 진행한다.
12. 마스터 브랜치로 돌아와 git pull
을 진행해 rebase를 완료한다.
rebase 추가사항 - gitHub에 PR날리고 다시 리팩토링을 해야 하는 경우
1. 코드 수정하고 git add
2. git commit -m "메세지"
3. git rebase -i master
4. confilct 있으면 수정하고
5. git push origin 피쳐브랜치 --force (force push는 본인 피쳐 브랜치에서만 해야 함)
commit의 history를 바꾸는 일은 중앙 저장소 입장에서 보았을 때, 또 다른 branch가 갈라졌다고 인식하기 때문이다. --f 를 하지 않은 경우, github은 다시 pull을 하고 merge를 하라고 제안한다. force push 는 내가 올리는 history를 그대로 받으라고 github에게 명령하는 것과 같다.
또, force push는 본인 브랜치에서만 진행해야 함!
master에서 진행하는 경우, 다른 사람들의 commit history 바꾸어 버리게 되기 때문이다.
git merge [branchname]
: 기준으로 잡고 싶은 브랜치로 git checkout
한 뒤 위의 명령어를 실행하면 branchname에 해당하는 브랜치가 현 위치 브랜치에 merge(병합)된다.
git merge --abort
: merge 직전의 상태로 돌아간다 git rebase -i [base재지정할 branch 대부분 master]
: --interactive 옵션을 사용하면, 커밋 로그를 조작할 수 있다. 즉, 불필요한 커밋 이력을 제거해서 필요한 커밋들만 남길 수 있습니다.
(커밋에서 작업했던 내용들은 그대로 유지)
git remote prune origin
: github에서 PR을 적용하고 merge 한 뒤에 원격 브랜치를 삭제하고 나면 로컬에는 삭제된 것이 적용 되지 않는다.
그러기 때문에 삭제된 브랜치를 로컬에도 적용시켜줘야 하는데 위의 명령어를 실행하면 로컬에서도 삭제된다.
1. master 브랜치에 rebase 성공한 뒤 delete branch 버튼을 두른 상황
2. git branch -a
로 브랜치 확인하면 삭제된 것이 반영이 안 됨
3.git remote prune origin
을 통해 원격 브랜치와 동기화 시켜 삭제를 적용
4.원격 브랜치 삭제 적용 완료!
git config color.ui true
: 콘솔에서 git output을 컬러로 출력하기
git config format.pretty oneline
: 이력(log)에서 확정본 1개를 딱 한 줄로만 표시하기