7. 적용한 작업 내용은 스택에서 없애기
이전 영상에서 배웠던 커맨드들을 잠깐 정리해보겠다.
1. 작업 내용 저장 : git stash
2. 작업 내용 조회(=스택 살펴보기) : git stash list
3. 작업 내용 적용 : git stash apply [작업 내용의 아이디]
* 작업 내용의 아이디를 생략하면 가장 최근의 작업 내용이 적용됨
4. 작업 내용 제거 : git stash drop [작업 내용의 아이디]
* 작업 내용의 아이디를 생략하면 가장 최근의 작업 내용이 제거됨
이전에 적용(apply)한 작업 내용은 스택에서 제거(drop)해주는 게 좋다고 했었다. 그래서 git stash apply를 쓰고 git stash drop을 바로 해줬었는데 사실 이런 식으로 번거롭게 할 필요없이, git stash pop [작업 내용의 아이디] 커맨드를 사용하면 작업 내용을 적용하면서 동시에 스택에서 제거도 해주는 커맨드가 있다. [작업 내용의 아이디]를 인자로 주지 않으면, 가장 최근에 한 작업 내용을 적용하면서 스택에서 제거한다.
앞으로 스택에 저장된 작업 내용을 working directory에 적용할 때
- 그 작업 내용을 나중에 또 쓸 필요가 있다면 git stash apply를
- 나중에 또 쓸 필요가 없다면 git stash pop을 쓰면 된다.
8. 필요한 커밋만 가져오는 git cherry-pick
1부터 숫자 n까지의 합을 구해주는 get_Sum 함수를 프리미엄 버전에 추가하려한다. 합을 구하는 가장 좋은 방법을 찾기 위해 먼저 test 브랜치에서 테스트를 진행한다.
test 브랜치로 이동 후 첫 번째 함수를 추가하고 커밋한다.
그런 다음 ver1은 지우고 두번째 함수를 작성하고 커밋을 완료한다.
이제 ver2의 get_Sum 함수를 프리미엄 브랜치에 적용해보겠다. 그러면 프리미엄 브랜치로 이동 후 test 브랜치를 머지하면 된다. 그런데!! get_Sum 함수의 ver1이 더 빠르고 정확하다고 한다.. 결론적으로 get_Sum 함수의 ver1만 필요한 상황이다. 이 함수만 가져오는 방법이 있을까?
커밋 히스토리에서 해당 커밋의 작업 내용만 가져오고 싶다. 이럴 땐 git cherry-pick [가져오고싶은 커밋 아이디] 를 사용하면 된다. 이 커맨드는 자신이 원하는 작업이 들어잇는 커밋들만 가져와서 현재 브랜치에 추가한다.
git cherry-pick 커맨드를 입력하면.. conflict 뜬다.ㅎㅎ
이전에서와 마찬가지로 필요없는 부분은 삭제하고 커밋하면 된다.
9. 여러 커밋을 하나의 커밋으로
프리미엄 브랜치에 factorial 함수를 추가해보겠다. 그런후 커밋까지 완료한다.
그런데 프로그래밍을 하다가 팩토리얼을 더 효율적으로하는 알고리즘을 찾았다고 가정해보자. 그러면 아래와 같이 코드를 수정하고 다시 커밋해주면 된다.
커밋 히스토리를 보면 팩토리얼 함수를 추가했던 커밋들이 보인다. 그런데 생각해보면 처음 팩토리얼 추가했던 커밋은 필요가 없는 것 같다. 이 커밋을 없었던 걸로 하고 싶은데 어떻게 하면 될까?
전에 배웠던 git reset 커맨드를 사용하면 된다. wroking directory의 상태를 건드리지 않는 옵션으로 --mixed 와 --soft 를 줄 수 있다.
나는 팩토리얼 함수가 아예 없었던 Add get_Sum function from test branch 커밋으로 돌아가겠다. 이때 working directory의 내용은 건드리지 않도록 --soft나 --mixed 옵션을 줘야 한다.
나는 git reset --soft 옵션을 사용했다. 이전 커밋으로 잘 돌아왔다!
그런 후 add 하고 커밋을 완료한다. 그러면 두개였던 Add factorial 커밋이 하나가 되었고, factorial 함수도 효율적인 모습을 하고 있을 것이다.
최대한 불필요한 커밋을 없애고 싶다면 이 방법을 활용해보자!!!
10. git이 무시하는 파일들
우리는 working directory에 있는 파일들을 git add, gid commit하면서 프로젝트를 버전 관리한다. 그런데 working directory 안에 있음에도 불구하고 Git에 의해 그 존재 자체가 무시되는 파일들이 있다.
지금 GitHub에서 Mathbox라는 레포지토리를 만들려고 하는데 여기서 화면 하단을 보면 Add .gitignore: None 이라는 설정 탭이 보인다. 이 말은.gitignore파일을 만들지 않겠다는 뜻이다.
.gitignore 파일은 working directory 내에 존재하는 파일들 중에서 마치 존재하지 않는 것처럼 Git이 인식해야할 파일들의 목록이 적힌 파일이다. 말그대로 Git이 ignore(무시)하는 파일들의 이름이 적혀있는 파일이다. 이 탭을 클릭해보면, 알파벳 A부터 순서대로 그 알파벳으로 시작하는 단어들이 등장한다.
이 단어들은 모두 프로그램이 실행되는 플랫폼이나 프로그래밍 언어들을 말한다. 이런 것들 중 하나를 선택하면 그 플랫폼에서 실행될 프로그램을 만들거나, 해당 프로그래밍 언어로 코드를 작성할 때 (보통 자동으로) 생성되는 파일들 중에서 굳이 Git에 의해 버전 관리될 필요가 없는, 불필요한 파일들의 이름이 정리된 .gitignore 파일을 자동으로 생성해준다.
파이썬을 선택하고 레포지토리를 생성하면 이렇게 .gitignore 파일이 생성된다.
클릭해서 내용을 보면 여러 파일 이름 또는 디렉토리 이름이 보인다.
이 중에서 몇 가지만 추려보겠다.
*.py[cod]
*$py.class
*.so
이것들은 모두 무슨 말일까? 여기서 * 는 그냥 길이 0개 이상의 아무 단어, 대괄호([ ])는 그 안의 알파벳 중에 하나라고 생각하면 된다.
그러니까 지금 이 3가지의 뜻은 아래 표와 같다.
*.py[cod] | .pyc 또는 .pyo 또는 pyd로 끝나는 파일명 |
*$py.class | $py.class로 끝나는 파일명 |
*.so | .so로 끝나는 파일명 |
여기에 해당하는 파일들은 모두 Git이 그냥 무시해버린다.
그리고 위 그림에서
- build/
- develop-eggs/
처럼 이름 맨 뒤에 슬래시(/)가 붙은 것은 디렉토리를 말한다. 이 2가지는 build 디렉토리에 있는 모든 파일과, develop-eggs 디렉토리에 있는 모든 파일들도 Git이 무시한다는 뜻이다.
이렇게 Python의 .gitignore 파일에는 파이썬으로 작업을 하다보면 생겨나는 여러가지 전형적인 부산물들의 이름이 적혀있다. 이것들은 딱히
- 버전 관리를 할 정도의 가치가 없고,
- 오히려 버전 관리를 하면 용량만 더 차지하고,
- 나중에 각 버전을 살펴볼 때 가독성을 떨어뜨리기만 하기 때문에
이렇게 Git이 무시하도록 설정한 것이다.
그럼 Git이 무시한다는 게 정확히 어떤 의미일까?
Mathbox라는 리모트 레포지토리를 GitHub에서 생성하고 git clone 커맨드로 이 리모트 레포지토리를 제 컴퓨터로 가져와보겠다. Mathbox 디렉토리 안으로 들어가서 확인해보면 .gitignore 파일을 볼 수 있다.
그 다음 이 working directory 안에서 calculator.py라는 파일과 library.so라는 파일을 생성했다.
그리고 바로 git status 커맨드로 확인해보면 아직 calculator.py 파일을 아직 git add하지 않았다는 결과가 출력된다.
그런데 library.so라는 파일도 분명히 생성했는데 왜 calculatro.py만 뜬 걸까? 앞서 Python의 .gitignore 파일에 써있던 *.so 표시에 따라 앞으로 Git은 이 working directory 안에서 .so라는 확장자로 끝나는 모든 파일들을 아예 무시하고 신경쓰지 않을 것이다.
이 상태에서 .gitignore 파일을 삭제하고 다시 확인해보면, 이번엔 library.so 파일도 git add 해주지 않았다는 경고가 뜨는 것을 볼 수 있다. .gitignore 파일이 삭제되어 Git이 이제 모든 파일을 인식하기 때문이다.
만약 working directory에서 버전 관리를 할 필요가 없는 것들이 있다면 이렇게 .gitignore 파일에 그 이름을 추가하고 버전 관리를 시작하면 좀 더 깔끔하게 버전 관리를 할 수 있다. 그리고 앞으로 어떤 파일들을 무시해야할지 잘 모르겠다면 위에서 봤던 것처럼 GitHub에서 기본으로 제공하는 각 플랫폼 또는 프로그래밍 언어별 .gitignore 파일을 참고하면 좋다.
11. Git 토픽 내용 총정리
2. Git 써보기
- git init : 현재 디렉토리를 Git이 관리하는 프로젝트 디렉토리(=working directory)로 설정하고 그 안에 레포지토리(.git 디렉토리) 생성
- git config user.name '[아이디]' : 현재 사용자의 아이디를 설정(커밋할 때 필요한 정보)
- git config user.email '[메일]' : 현재 사용자의 이메일 주소를 설정(커밋할 때 필요한 정보)
- git add [파일 이름] : 수정사항이 있는 특정 파일을 staging area에 올리기
- git add [디렉토리명] : 해당 디렉토리 내에서 수정사항이 있는 모든 파일들을 staging area에 올리기
- git add . : working directory 내의 수정사항이 있는 모든 파일들을 staging area에 올리기
- git reset [파일 이름] : staging area에 올렸던 파일 다시 내리기
- git status : Git이 현재 인식하고 있는 프로젝트 관련 내용들 출력(문제 상황이 발생했을 때 현재 상태를 파악하기 위해 활용하면 좋음)
- git commit -m "커밋 메시지" : 현재 staging area에 있는 것들 커밋으로 남기기
- git help [커맨드 이름] : 사용법이 궁금한 Git 커맨드의 공식 메뉴얼 내용 출력
3. GitHub 시작하기
- git push -u(또는 --set-upstream) origin master : 로컬 레포지토리의 내용을 처음으로 리모트 레포지토리에 올릴 때 사용
- git push : 위의 커맨드를 한번 실행하고 난 후에는 git push라고만 쳐도 로컬 레포지토리의 내용을 리모트 레포지토리에 올릴 수 있음
- git pull : 바로 위의 위에 있는 커맨드를 한번 실행하고 난 후에는 git pull이라고만 쳐도 리모트 레포지토리의 내용을 로컬 레포지토리로 가져옴
- git clone [프로젝트의 GitHub 상 주소] : GitHub에 있는 프로젝트를 내 컴퓨터로 가져오기
4. Git에서 커밋 다루기
- git log : 커밋 히스토리를 출력
- git log --pretty=oneline : --pretty 옵션을 사용하면 커밋 히스토리를 다양한 방식으로 출력할 수 있다. --pretty 옵션에 oneline이라는 값을 주면 커밋 하나당 한 줄씩 출력. --pretty 옵션에 대해 더 자세히 알고싶으면 링크를 참고
- git show [커밋 아이디] : 특정 커밋에서 어떤 변경사항이 있었는지 확인
- git commit --amend : 최신 커밋을 다시 수정해서 새로운 커밋으로 만듦
- git config alias.[별명] [커맨드] : 길이가 긴 커맨드에 별명을 붙여서 이후로는 별명으로도 해당 커맨드를 실행할 수 있게 설정
- git diff [커밋 A의 아이디] [커밋 B의 아이디] : 두 커밋 간의 차이 비교
- git reset [옵션] [커밋 아이디] : HEAD가 가리키는 브랜치를 이동. 옵션에 따라 하는 작업이 달라짐(옵션을 생략하면 --mixed 옵션이 적용됨)
- git tag [태그 이름] [커밋 아이디] : 특정 커밋에 태그를 붙임
5. Git에서 브랜치 사용하기
- git branch [새 브랜치 이름] : 새로운 브랜치를 생성
- git checkout -b [새 브랜치 이름] : 새로운 브랜치를 생성하고 그 브랜치로 바로 이동
- git branch -d [기존 브랜치 이름] : 브랜치 삭제
- git checkout [기존 브랜치 이름] : 그 브랜치로 이동
- git merge [기존 브랜치 이름] : 현재 브랜치에 다른 브랜치를 머지
- git merge --abort : 머지를 하다가 conflict가 발생했을 때, 일단은 머지 작업을 취소하고 이전 상태로 돌아감
6. Git 실전 I
- git fetch : 로컬 레포지토리에서 현재 HEAD가 가리키는 브랜치의 업스트림(upstream) 브랜치로부터 최신 커밋들을 가져옴(가져오기만 한다는 점에서, 가져와서 머지까지 하는 git pull과는 차이가 있음)
- git blame : 특정 파일의 내용 한줄한줄이 어떤 커밋에 의해 생긴 것인지 출력
- git revert : 특정 커밋에서 이루어진 작업을 되돌리는(취소하는) 커밋을 새로 생성
7. Git 실전 Ⅱ
- git reflog : HEAD가 그동안 가리켜왔던 커밋들의 기록을 출력
- git log --all --graph : 모든 브랜치의 커밋 히스토리를, 커밋 간의 관계가 잘 드러나도록 그래프 형식으로 출력
- git rebase [브랜치 이름] : A, B 브랜치가 있는 상태에서 지금 HEAD가 A 브랜치를 가리킬 때, git rebase B를 실행하면 A, B 브랜치가 분기하는 시작점이 된 공통 커밋 이후로부터 존재하는 A 브랜치 상의 커밋들이 그대로 B 브랜치의 최신 커밋 이후로 이어붙여짐(git merge와 같은 효과를 가지지만 커밋 히스토리가 한 줄로 깔끔하게 된다는 차이점이 있음)
- git stash : 현재 작업 내용을 스택 영역에 저장
- git stash apply [커밋 아이디] : 스택 영역에 저장된 가장 최근의 작업 내용을 working directory에 적용
- git stash drop [커밋 아이디] : 스택 영역에 저장된 가장 최근의 작업 내용을 스택에서 삭제
- git stash pop [커밋 아이디] : 스택 영역에 저장된 가장 최근의 작업 내용을 working directory에 적용하면서 스택에서 삭제
- git cherry-pick [커밋 아이디] : 특정 커밋의 내용을 현재 커밋에 반영
- git push와 git pull은 그 작업 단위가 브랜치이다. 예를 들어, master 브랜치에서 git push를 하면 master 브랜치의 내용만 리모트 레포지토리의 master 브랜치로 전송되지, premium 브랜치의 내용이 전송되는 것은 아니다.(git push에 --all이라는 옵션을 주면 모든 브랜치의 내용을 전송할 수 있다.)
Git 토픽 끝!!!!!!
'1. 프로그래밍 > 1-1. Git' 카테고리의 다른 글
Git - [ eclipse 프로젝트 Github 올리기 ] (0) | 2022.04.01 |
---|---|
Git - [이전 커밋 이름 변경하기] (0) | 2022.02.26 |
7. Git 자유자재로 활용하기 (0) | 2021.09.06 |
6. Git 협업하기 (0) | 2021.09.05 |
5. 브랜치 사용하기 (2) - [ git reset / checkout / merge ] (0) | 2021.09.05 |