GIT

yo·2020년 6월 3일
0

git 이론과 실습

git init

"현재 디렉토리에서 git 작업 진행할 것을 선포한다."
-프로젝트 진행 할 디렉토리에서 해야됨!!
-ls -al 입력 시 .git 생긴 것 확인 가능.

git add

프로젝트 디렉토리에서 f1.txt파일을 만들고 작업했다.

git status로 보면 아래와 같은 메세지가 뜬다.

No commits yet

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

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

add와 commit을 하기 전까지 git은 파일들을 무시한다.
이 떄 add명령을 줘서 내가 만든 파일을 깃이 인식하도록 해야한다.

git add f1.txt

git config

git config --global user.name kimhi kpl5672@gmail.com
지금부터 만들 버전은 내가 만든 것이라고 다른사람에게 알려주기 위의
위의 형태로 한 번 입력해준다.

git commit

git commit을 치면 입력창이 뜬다.
i를 눌러 인서트 기능 활성화.
쓸 내용을 쓴 뒤 esc, :wq

git log

잘 커밋 되었는지 확인할 수 있다.

방금 커밋한 f1.txt파일의 내용을 또 다시 수정하게 된다면?? modified라고 뜬다.

❯ vim f1.txt   #수정했음
❯ git status    #상태확인
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   f1.txt

no changes added to commit (use "git add" and/or "git commit -a")

다시 add->commit과정을 다시 거쳐야 한다.

add, commit에 대해.

cp f1.txt f2.txt로 f1.txt파일을 복사해 f2.txt라는 새파일을 만들었다.
그다음, f1.txt, f2.txt를 각각 수정한다.
이 때 git status를 보면 아래오 ㅏ같다.

다음, f1.txt는 add를 하고, f2.txt는 add하지 않았다 치자.
status는 아래와 같다.

이때 git commit을 실행하면 결과는 아래와 같다.

결론: 복수의 파일이 있을 때 선택적으로 add를 해서 commit을 위한 stage로 올리고,
결국 선택적으로 commit할 수 있다. 이게 왜 혁신이냐면, 예전 버전관리시스템에선 복수의 파일을 수정하면 모두 다 commit을 할 수 밖에 없었다고 함.
stage-repository가 존재한다.
stage는 add해서 올라가고 commit대기실.
repository는 commit해서 올라간 저장소.

git log, diff에 대해.![]

git log -p : 내용변동사항까지 보여주는 로그(https://images.velog.io/images/kpl5672/post/32ccc7f0-6579-4701-a23c-f7370f067374/Screen%20Shot%202020-06-04%20at%208.10.19%20AM.png)

+++는 현재 파일, ---는 이전 버전 파일.
+는 현재 파일 내용, -는 이전 파일 내용.
---/dev/null은 이전 버전에서 파일이 없었다는 뜻.

log id


git log시 나오는 아이디들은 고유하다.
아이디를 복사해서 git log 아이디를 쓰면,
해당 아이디 기준 이전 내용들이 나온다.

git diff

1)두 커밋 사이의 차이점을 알고 싶다면,
git diff 아이디1..아이디2를 입력한다.

2)어떤 파일이든지 수정하고 난 다음에, git diff를 써보면, 이전 커밋버전과 지금 내가 수정한 것의 차이를 알 수 있다. 이 과정은 반드시 add하기 전에 해야된다.
add하고 나면 해당 기능은 작동하지 않는다.

reset

-현재의 커밋 버전이 5인데 3번으로 돌아가고 싶다면?
->reset과 revert가 있다.
우선 reset알아보자.

git reset log_id --hard

-이렇게 했다고 날라간 버전들은 버려진게 아니다.원한다면 복구할 수 있다.
-그런데, 깃허브에 공유한 이후에는 리셋하면 안된다.
공유하기 이전 내 로컬컴퓨터에 있는 버전에 대해서만 리셋해야한다.
-hard는 위험한 방법이고, soft등등이 있는데 일단 hard쓰자.

git 관련 구글 검색어 통계

git commit -a

원래는 파일 수정 후 add->commit과정 거쳐야 한다.
git commit -a는 수정, 삭제된 파일을 한번에 add와 commit해주면서 commit입력창으로 넘어가게 해준다.
*중요한 것은, 이미 한 번 add가 된 파일에 대해서만 해당한다는 것이다.
처음 add하는 경우라면 위코드로 add불가능.

git commit -m "msg"

커밋시 입력창으로 넘어가지 않고 바로 메세지 칠 수 있게 해준다.

git commit -am "msg"

수정된 파일을 한 번에 에드, 커멧, 메세지 작성하는 기능.

git의 원리분석

branch

git branch

현존하는 브랜치 목록 보여준다.
별표가 있는 브랜치가 지금 내가 있는 브랜치

git branch new_branch_name

새로운 브랜치를 생성하는 코드

git checkout branch_name

현재 있는 브랜치에서 체크아웃하고 다른 브랜치로 들어가는 기능.
<중요> a브랜치에서 b브랜치를 생성하면 b는 a의 모든 내용을 그대로 이어받는다.

git branch -d branch_name

브랜치를 삭제한다. 머지를 하지 않았을 경우 에러 경고문이 나올 수 있다.
이때 git branch -D branch_name로 강제삭제 할 수 있다.

브랜치 중요개념

master브랜치의 1.txt는 a라는 내용이다.
여기서 git branch new 로 new라는 branch를 만들고 거기로 이동한 후,
1.txt파일을 b라는 내용으로 수정한 뒤 에드, 커밋한다.
new branch에서 git log로 확인하면 기록이 나온다.
반면, git checkout master를 한 뒤 git log를 보면 나오지 않고,
1.txt파일의 내용도 그대로 a이다.
서로 다른 브랜치에서 한 일이기 때문이다.

git log --branches --docorate

일반적으로 쓰는 git log는 현재 속한 브랜치의 로그를 보여준다.
반면,git log --branches --decorate는 모든 브랜치의 로그를 한 번에 보여준다.

사진설명
현재 exp브랜치에 있다.(HEAD ->exp)
exp브랜치와 master브랜치의 최근 로그를 볼 수 있다.

git log --branches --decorate --graph

마스터브랜치, 분기한 브랜치들와 진행상황을 시각화해서 보여준다.

git log --branches --decorate --graph --oneline

-브랜치 관계를 간결하게 조망할 수 있다.

tree

소스트리. 깃의 gui툴. 브랜치 관계 보여줌

branch-branch간의 차이점 알아보기

git log master..exp

마스터 브랜치와 exp브랜치의 차이점
(마스터에는 없고 exp브랜치에는 있는 것.)

git log exp..master

exp브랜치과 master branch의 차이.
(exp에는 없고, master branch에는 있는 것.)

git log -p exp..master 혹은 git log -p master..exp

단순 차이점 말고 소스코드의 차이점까지 보이기.

git diff master..exp

브랜치의 현재 상태를 비교
---는 마스터, +++는 exp

branch merge


위처럼 master와 exp가 있는 상태에서, exp를 master로 merge 시키려면?
1) master로 이동한다. (checkout master)
2)git merge exp명령어 친다.
3)아래처럼 exp를 branch로 머지했다는 창이 뜬다. :wq로 나가면 merge완성.

관계도를 확인해 보면 아래와 같이 바뀌었다.

4)이전 브랜치를 삭제하려면, master브랜치에 있는 상태에서 git branch -d exp를 입력하면 된다.

*중요 관계를 헷갈리면 큰일난다. a branch->b branch로 merge하려면 b브랜치에서 git merge a를 입력해야 한다.

git merge fast-forward, recursive

  1. 마스터브랜치에서 3번 커밋작업을 진행한 상태이다.

2.이 때 이슈가 발생, 문제를 해결하기 위해 새로운 iss53이라는 브랜치를 만들고 이동한다.
git checkout -b iss53

3.iss53에서 내용을 수정하고 커밋을 한다.

vim index.html
git commit -a -m 'added a new footer [issue 53]'

4.갑자기 마스터브랜치에서 해결해야 할 문제가 발생한다. 이를 위해 hotfix라는 브런치를 생성하고 내용을 수정한다.

  1. hotfix는 긴급한 문제였기에, 해결 후 마스터브랜치로 merge를 한다.

    fast-forward는 빨리감기.
    hotfix가 만들어진 이후로, master branch에는 아무런 변화가 생기지 않았다.
    그러므로 hotfix를 master에 merge하는 과정은, 단순히 master가 가리키는 커밋을 hotfix가 가리키는 커밋으로 '빨리감기' 하는 것에 다름 아니다. 결과는 아래와 같다.
    즉, 별도의 커밋을 생성하지 않고 master의 커밋을 바꾼다.

  2. 이제 hotfix는 필요가 없기에 지워준다.
    git branch -d hotfix

7.다음으로 원래 하려던 iss53으로 체크아웃 해서 내용을 수정하고 커밋해준다.

  1. 이제 iss53작업이 끝났으니, master로 checkout해서 iss53을 merge한다.
git checkout master
git merge iss53

하면 이런 문구가 뜬다. "Merge made by the 'recursive' strategy."
자세히 설명해보겠다.
무슨 소리냐면, iss53이 마스터로부터 독립한 이후에, 마스터에도 변화가 생겼다.
이 경우에는 fast-forward방식을 쓸 수 없다.

이런 상황에서 merge할 경우 깃의 동작 메커니즘은 다음과 같다.
1. 마스터와 iss53의 공통조상을 찾는다.
2. three way merge라는 방식으로 c4와 c5를 합치고, 둘을 합친 정보를 갖는 별도의 커밋 c6를 만든다.

stash

git 충돌해결

<시나리오1>
1. 2개의 브랜치(master, a)가 있다. a는 master에서 파생된 브랜치.
2. master에 1.txt파일이 있고 a에 2.txt파일이 있다.
3. 둘을 merge할 때, 서로 다른 파일을 가지고 있기에 아무 문제 없이 merge가 된다.
4. master에서 a를 merge했다면 결과는 1.txt, 2.txt파일을 둘다 가지는 것.

<시나리오2>
1. 2개의 브랜치(master, a)가 있다. a는 master에서 파생된 브랜치.
2. master에 1.txt파일이 있고 a에도 1.txt파일이 있다.
3. 각각의 브랜치에서 1.txt파일을 수정한 후 merge한다.
4. 1.txt파일의 원래 내용은 2 달랑 한 글자이다.
master에선 아래와 같이 수정했고,

1
2

a 브랜치에선 아래 처럼 수정했다.

2
3

5.이 후 두 a를 master로 merge하면 별 문제 없이 된다. 같은 부분을 겹치게 수정하지 않았기 떄문이다. 머지 후 1.txt파일의 내용은 아래와 같다.

1
2
3

<시나리오3> 불행의 시나리오.
1. 2개의 브랜치(master, a)가 있다. a는 master에서 파생된 브랜치.
2. master에 1.txt파일이 있고 a에도 1.txt파일이 있다.
3. 각각의 브랜치에서 1.txt파일을 수정한 후 merge한다.
4. 1.txt파일의 원래 내용은 print()이다.
master에선 아래와 같이 수정했고,

print("hello")

a 브랜치에선 아래 처럼 수정했다.

print("world")

5.이제 master에서 a를 merge하면 confilct error가 발생한다.

"You have unmerged paths.
(fix conflicts and run "git commit")
both modified.

대충 이런식의 메세지.
컴퓨터 입장에서, 한쪽은 이렇게 하라는데, 다른쪽에선 저렇게 하라하고, 그 둘을 합치라니 어쩔 줄 모르는거다. 그래서 사용자에게 알아서 수정하라고 그 일을 위임한다.

이제, 1.txt파일을 들어가서 수정해야한다. 아래 사진은 다른 예시이긴 한데 하여튼 비슷하다.
중간에 있는 =======은 구분자다. 구분자를 중심으로 위쪽 <<<<<HEAD는 현재 내가 체크아웃 해있는 브랜치이다. 아래>>>>>>는 머지하려는 대상브랜치다.

구분자 같은 표시들은 다 지우고,내가 원하던 형태가 뭐였던지 수동으로 바꿔서 만들어줘야한다.

이렇게 바꾼 후에 해당 파일을 add, commit하고, 다시 merge를 하면 된다.

----생활코딩 git강의 29강 시청차례.------

profile
Never stop asking why

0개의 댓글