지금까지 우리는 GIT이 어떤 개념이 있고 어떤 방식으로 돌아가는지 배웠다.
그런데... 막상 바로 실무에서 사용하기에에느느으으은.. 조오오그음.. 부족한 감이 없잖아 있다!
그래서 실무에서 사용되는 내용들을 정리해서 글을 써놓으려 한다.
다른 개발자가 먼저 Git push를 해버렸다면..?
이 상황은 로컬 레포와 리모트 레포의 커밋이 다를 때, 즉 한 프로그램을 다른 개발자들과 협업할 때 자주 일어난다.
로컬 레포를 수정하는 동안 리모트 레포가 바뀐다면,,, 바로 git push를 할 수 없다.
그래서 보통 git pull로 내용을 가져와서 커밋을 만든 후에, 다시 push를 해주는데...
그런데 git pull을 할 때 에러가 뜬다.
그래도 다행히 merge conflict 에러라서 쉽게 해결이 가능하다!
git pull은 리모트 레포지토리의 브랜치를 가져와서 현재 브랜치에 merge하는 커맨드이다.
그리고 나서 git push를 해주면 해결 완료!
정리
개발자 B가 push를하면, A는 바로 push를 할 수없다.
따라서 git pull로 리모트 레포지토리의 브랜치를 가져와서, 로컬 레포지토리의 브랜치에 merge한 뒤에,
merge conflict가 발생하면 이를 해결 후에, git push를 해주면 정상적으로 push가 된다.
Git pull 하면 merge되는데.. 함부로 해도 되나?
우리가 사용해온 git pull은 자동으로 리모트 레포에서 브랜치를 가져와서 merge하는 커맨드인데...
merge는 함부로 하면 안된다.
따라서 이를 막기위해 우리는 일단! 브랜치의 내용만 가져와서 살펴보고, merge하고 싶을 때
git fetch
를 사용한다.
즉 git pull을 해서 바로 merge하기 의심스러울 때(뭐.. 신입 개발자가 push를 한 상황이라던가.. 반영환이 말도 안하고 함부로 push해놨다던가.. 할 때) git fetch를 사용한다.
그리고 git diff를 이용해 차이를 확인한 후에 원하는 내용만 merge해주면 된다.
정리
"리모트 레포지토리의 브랜치에 문제가 있네!"
1. 잘못된 코드를 추가한 개발자를 찾아가서 다시 리모트에 푸쉬해달라고 하기.
2. 잘못된 부분을 알아서 해결하고 다시 git push하기
??? : 어 뭐야 이 코드 누가 커밋했어?
이런 상황...에서.. 우리는 보통 내 탓이 아니라고 우기거나 남 탓을 하기 시작한다.
git은 개발자들이 잘못된 코드를 커밋하지 않게 하기 위해 이러한 커맨드를
git blame
이라고 한다. (진짜임)
git blame fileName를 통해 커밋ID를 찾고
git show 를 통해 커밋 메시지를 확인해주면 된다.
아...잘못 올렸다...
리모트 레포에 잘못 커밋을 해서 올라갔을 때... 어떻게 해야할지...
이럴 때 사용하는 것이
git revert
이다.
git revert returnCommitID
그런데.. 걍 git reset을 해주면 되는거 아니야??
안된다!
로컬 레포에서만 작업을 한다면 상관이 없지만... 리모트에서도 작업을 한다면 문제가 생긴다.
커밋의 버전이 달라서 push할 수 없기 때문!
이에따라 revert는 새로운 커밋을 생성한다는 특성이 있기 때문에 리모트 레포지토리에 같은 내용을 push해 줄 수 있다.
여러 개의 커밋 취소
git revert 시작CommitID..끝CommitID
*시작 CommitID 이후 커밋부터 revert된다.
커맨드 정리
git fetch : 로컬 레포지토리에서 현재 HEAD가 가리키는 브랜치의 업스트림(upstream) 브랜치로부터 최신 커밋들을 가져옴(가져오기만 한다는 점에서, 가져와서 머지까지 하는 git pull과는 차이가 있음)
git blame : 특정 파일의 내용 한줄한줄이 어떤 커밋에 의해 생긴 것인지 출력
git revert : 특정 커밋에서 이루어진 작업을 되돌리는(취소하는) 커밋을 새로 생성
??? : 아까 말한거 거기 말고 좀 더 앞으로 되돌려놔
헉... 난 이미 reset으로 이전 커밋으로 돌아갔는데.. 이거 삭제된거 아니야?
아니다. reset을 해도 이후 커밋들이 삭제되거나 하는건 아니다. (이거 적었던거 같은데 기분탓인가?)
1. 커밋 아이디를 안다면 다시 돌아갈 수 있다.
2. 커밋 아이디를 모른채 git reset을 했다면...
1의 경우는 문제없지만, 2의 경우는...
사실 이것도 문제없다 ㅇㅇ
git reflog
를 이용하면 커밋 아이디를 찾을 수 있다.
reflog에서 HEAD@{index}도 커밋 아이디처럼 사용될 수 있다.
reflog란 reference log의 준말로 헤드가 이때까지 가리켜왔던 커밋들을 기록한 로그이다.
다만 reset은 commit한 내용에 대해서만 돌아갈 수 있다!
커밋 히스토리 어떻게 보더라..
- git log --pretty=oneline
- aliasing 1. to git history
근데 이건 하나의 브랜치에서 작업한 커밋만 볼 수 있다.
그러면 다른 브랜치의 커밋을 보려면?
git log --pretty=oneline --all
을 해주면 된다.
근데 이렇게만 보면 또 햇갈린다. 브랜치별로 구분이 안가기 때문에
따라서
git log --pretty=oneline --all --graph
를 이용해서 히스토리를 보면 더 좋다!
GIT을 GUI 환경에서 사용하는 법
source tree라는 프로그램을 통해 편하게 git을사용할 수 있다.
하지만 커맨드와 개념을 미리 알고나서, 이런 도구를 사용해야 현명히 사용할 수 있으므로 나중에 쓰자!
https://support.atlassian.com/bitbucket-cloud/docs/tutorial-learn-bitbucket-with-sourcetree/
커밋 히스토리 이거 이거 더러워서 원...
흠... 계속 merge merge merge 하다보니까 커밋루트가 너무 더럽게 꼬여지는거 같다.
이를 해결하려면
git rebase targetBranchName
를 사용해보자.
rebase는 커밋을 재배치 하는 것이다. A 브랜치의 베이스를 B 브랜치로 재지정한다는 것인데 아래 사진과 같다.
또 하나, merge는 conflict가 생기면 커밋을 통해 해결했지만
rebase는 git rebase --continue를 통해 해결한다.
정리
git merge는 merge 커밋이 생성되지만
1. git rebase는 새로운 커밋을 만들지 않는다.
2. rebase로 만든 커밋 히스토리는 merge로 만든 것보다 깔끔하다.
*rebase나 merge의 결과물은 같다.
쓰는이유 : 커밋히스토리를 깔끔히 만들기위해서.
두 브랜치가 merge된 내용이 남아야한다면, merge사용
커밋히스토리가 깔끔한게 더 중요하다면 rebase 사용
??? : 그거 지금 하지말고 당장 B 브랜치로 넘어가서 작업해
에... 지금 하던거도 있는데 ... 브랜치 넘어가면 워킹디렉토리의 내용도 브랜치의 커밋 내용으로 대체될탠데..
지금까지 한거 날라가는거 아니야..?
이런 상황을 위해 필요한 것이 바로
git stash
이다. working directory에서 작업하던 내용을 git이 따로 stack에 보관하는 것이다. (stack은 모든 브랜치가 공유한다)
git stash list로 stack 저장내용 확인한다.
git stash를 하면 최근 커밋 이후로 작업했던 내용은 모두 스택으로 가고, working directory의 내부가 최근 커밋상태로 초기화된다.
git stash apply로 working directory에 스택에 있던 내용을 가져와서 저장한다.
어.. A에서 해야하는데...모르고..B에서.... 아...
당황하지말고 이것도 git stash를 사용해라.
git stash
git checkout A
git stash list
git stash apply stash@{index}
이렇게 해주면 conflict가 발생하므로 해결해주면 끝!
즉)
1. git stash로 stack에 작업내용을 저장하고
2. 올바른 브랜치로 가서 git stash apply를 한다.
3. 이미 적용한 작업내용은 지워주자!
- git stash drop stash@{index}
git stash pop [ID]
= git stash apply [ID] + git stash drop [ID]
ID값을 주지 않으면 가장 최근에 한 작업 내용을 적용하면서 스택에서 제거해준다.
어.. 나 커밋 다 필요없는데.. 이것만 가져오면 좋을 거같은데
내가 필요한 것만 가져오는 사람을 우리는 cherry picker라고 한다... git도 이런 행위를 cherry-pick이라고 한단다.
git cherry-pick commitID
자신이 원하는 작업이 들어있는 커밋들만 가져와서 브랜치에 추가해준다.
또 커밋을 두 개 해놓은 상태에서 하나의 커밋만 사용하고 싶고... 나머지는 필요 없을거 같을 때..
reset의 --mixed 옵션과 --soft 옵션을 이용해 현재 작업했던 코드 이전의 가장 최근의 커밋으로 돌아가면 된다.
이러면 workingdirectory는 안전하다!
그리고나서 git add .; git commit ~~ 해주면!
커밋은 필요한 하나만 히스토리에 남게된다.
.gitignore
working directory 내에 존재하는 파일들 중에서 마치 존재하지 않는 것처럼 Git이 인식해야할 파일들의 목록이 적힌 파일이다.
이것들은 딱히 버전 관리를 할 정도의 가치가 없고, 오히려 버전 관리를 하면 용량만 더 차지하고,
나중에 각 버전을 살펴볼 때 가독성을 떨어뜨리기만 하기 때문에 이렇게 Git이 무시하도록 설정한 것.
리모트 레포 만들 때 gitignore 설정에서 프로젝트에서 사용하는 프로그램에 따라 권장되는 gitignore 설정해주면 된다.
이미 만든 레포지토리에서 gitignore 만들기
1. .gitignore 파일만든 후, 무시하고 싶은 파일들을 적어서 push
2. 프로젝트에 사용하는 프로그램에 따라 권장되는 gitignore를 만들어주는 사이트 : https://www.gitignore.io/
참고!
드디어 git이 끝났다... 어후 지루해 당장 쓸 곳은 많이 없겠지만 뭐 필수니까! 미리 정리해놔서 나쁠 건 없지!
이제 네트워크공부랑 알고리즘공부 좀 더 집중해서 시작해야겠다. 지금까지 잘 해왔으니 더 잘 할 수 있을거야!
드디어 일병 달았으니 더 열심히 해서 인정받으면서 살아보자 파이팅!
2021-10-01
'DevOps > Git' 카테고리의 다른 글
Github Authorization (0) | 2025.01.06 |
---|---|
4. 커맨드 모음 (0) | 2021.10.01 |
2. 브랜치 다루기 (0) | 2021.09.26 |
1. Commit 다루기 (0) | 2021.09.21 |
GIT 오픈소스 (0) | 2021.09.11 |