[Git] 너 git 알아? 난 몰랐다 🥹

Git이란?

분산형 소스코드 버전 관리 시스템

  • 이력 기록 및 추적 : 누가 언제, 어떤 파일을, 어떻게 수정했는지 변경 이력을 기록한다.
  • 원격 저장소 및 공유 : 서버 역할을 하는 원격 저장소와 각 개발자의 지역 저장소에 소스코드를 분산하여 저장한다.
  • 변경 이력 병합 : 각 개발자가 동일한 소스코드를 변경하는 일이 빈번히 발생하므로 하나의 소스코드 파일에 대한 여러 변경 이력을 통합하는 기능

 

github

git으로 관리하는 프로젝트를 올려둘 수 있는 호스팅 사이트

 

git의 작업 영역

﹅ Working Directory

tracked 파일들이 위치하는 영역
.git 폴더를 제외한, 작업된 파일이나 코드가 저장되는 공간

﹅ Staging area

commit할 대상 파일들이 위치하는 영역

﹅ Repogitory

commit 된 파일들이 위치하는 영역

 

Git이 관리하는 파일 상태

  • untracked : 작업진행중인 작업 디렉토리에서 새로 생성된 파일
  • modified : 관리대상 파일이 수정되고 commit 되지 않은 상태
  • staged : 수정된 파일이 staging area에 있는 상태 (add 하는 순간)
  • unmodified : 파일 변경사항 기록이 완료된 상태

 

Git 명령어

  • git init : 지역 저장소를 생성한다.
  • git status : 현재 repogitory의 상태를 보여준다.
  • git add "파일명": 커밋에 포함될 파일을 등록한다.
  • git add . / git add -A : 등록가능한 모든 파일을 등록한다.
  • git commit -m "커밋내용" : 새로운 커밋을 생성한다.
  • git commit -am "커밋내용" : add 와 커밋을 한번에 진행한다.
  • git log : 커밋 내역을 확인한다. (커밋 아이디 확인 가능)
  • git log --oneline : 로그를 한줄로 약식으로 보여준다.
  • git log --oneline --graph : 로그를 한줄로 그래프형식으로 보여준다.
  • git checkout <커밋아이디 앞7자리> : 해당하는 커밋 지점으로 파일을 되돌린다.
  • git checkout - : 바로 이전 커밋으로 되돌린다.
  • git remote add origin "원격저장소의 주소" : 원격저장소의 주소를 지역 저장소에 등록한다.
  • git push origin <브랜치이름> : 원격저장소에 커밋을 반영한다.
  • git commit --amend : 바로 이전 커밋을 수정할 수 있다.
  • git commit --amend -m "커밋메시지" : 바로 이전 커밋의 커밋메시지를 수정할 수 있다.
  • git commit --amend --author "저자" : 바로 이전 커밋의 저자정보를 수정할 수 있다.
  • git commit --amend --no-edit : 바로 이전 커밋을 커밋메시지를 수정하지 않고 커밋할 수 있다.
  • git clone "원격저장소 주소" : 로컬에서 폴더 생성 후 원격저장소를 복제한다.
  • git restore --staged <파일>: staging area에 있는 파일들을 working directory로 복원해오는 데 사용된다.
  • git restore <파일>: 변경된 파일을 마지막 커밋 상태로 되돌리는 데 사용된다.
  • git rm --cached : staging area 에서 파일을 제거할 때 사용된다.
  • git rm <파일> : 파일을 완전히 삭제할 때 사용된다.
  • git ls-files : git에서 관리하는 파일 목록을 보여준다.
  • git ls-files -o : git에서 관리하지 않는 파일 목록을 보여준다.
  • git ls-files | grep <원하는 내용> : git에서 관리하는 파일 목록을 원하는 내용만 필터링한다.

 

Git branch

branch 명령어

  • git branch <이름> : 브랜치를 생성한다.
  • git branch : 브랜치 전체 보여준다.
  • git branch -a : 브랜치 전체 보여준다. (로컬, 원격 모두 보기)
  • git checkout <이름> : 브랜치를 전환한다.
  • git switch <이름> : 브랜치를 전환한다.
  • git checkout - : 이전 브랜치로 전환한다.
  • git checkout -b <이름> : 브랜치를 생성 및 전환한다.
  • git switch -c <이름> : 브랜치를 생성 및 전환한다.
  • git branch -v : 브랜치 정보를 보여준다.
  • git branch -vv : 더 자세한 정보를 보여준다.
  • git log <브랜치이름>
  • git diff origin/main..HEAD : HEAD와 main 브랜치를 비교한다.
  • git diff origin/main..HEAD~1 : HEAD~1과 main 브랜치를 비교한다. (오른쪽 기준으로)
  • git remote prune orgin : local에서 remote에 없는 브랜치를 제거한다.

branch with remote

  1. git remote -v : 원격저장소 링크
    git remote show origin : 원격저장소 링크, 정보까지 보기
  2. git push -u origin <이름> : 해당 원격저장소 branch에 push
  3. 다른 폴더 -> git clone <원격저장소 링크>
    다른 동료의 폴더 -> git pull origin <브랜치>
    git checkout -b <브랜치> orgin/<브랜치>
  4. git checkout main : 메인 브랜치로 전환
    git merge <브랜치> : 해당 브랜치를 메인에 merge

branch 삭제

  • git branch -d <브랜치>
  • git branch -D <브랜치> : 커밋이 남은 경우 등등 강제로 브랜치를 삭제한다.
  • git push origin --delete <브랜치> : push를 이용하여 원격 브랜치를 삭제한다.
    git push origin -d <브랜치>

cf. github bug repo history 완전 삭제

oAuth 토큰이나 민감한 정보가 포함된 경우에 진행한다.

  1. BGF 설치
  2. 삭제 작업

 

Git stash & clean

아직 commit을 할 수 없는 작업중에 갑자기 수정사항이 생긴 경우
현재 작업을 임시저장하고 fetch 하자!

stash

  • git stash / git stash save "내용" : 스택에 임시저장된다.
  • git stash list : stash에 저장된 목록을 보여준다.
  • git stash show : stash 로그를 보여준다.
  • git stash show -p : stash 로그를 상세히 보여준다.
  • git stash pop : stash에 넣어뒀던 부분을 삭제 및 적용한다.
  • git stash drop : 가장 최근 stash를 삭제한다.
  • git stash stash@{stash list에 뜨는 id} : 해당하는 stash를 삭제한다.
  • git stash clear : 모든 stash를 삭제한다.
  • git stash branch <브랜치> : 현재 작업중인 내역으로 새로운 브랜치를 생성한다.
  • git stash apply stash@{stash list에 뜨는 id} : 원하는 stash를 적용한다.(삭제되지는 않으므로 drop과 함께 사용하자)

clean

  • git clean -n : git clean을 실행할때 삭제될 목록을 출력해준다.
  • git clean -di : ignore 파일 제외하고 나머지 파일을 안전하게 삭제한다.
  • git clean -df : ignore 파일 제외하고 나머지 파일을 묻지않고 삭제한다.
  • git clean -xi : ignore 파일 포함 안전하게 삭제한다.
  • git clean -xf : ignore 파일 포함 묻지않고 삭제한다.
  • git clean -X : ignore에 있는 파일만 삭제한다.

 

Git merge & rebase

﹅ Fast-Forward merge

시간의 흐름대로 커밋된 내용을 병합한다.
충돌 발생이 없고, 100% auto merge 된다.
merge 후 모든 커밋이 복제된다.

﹅ 3-Way merge

두 개 이상의 브랜치로 파생된 커밋을 병합한다.
충돌 가능성이 있다.
병합 메시지가 존재한다.

﹅ Rebase

공통조상(base)을 병합한다.
3-Way -> Fast-Forward화 된다. (3-Way merge를 사전에 방지)
주기적으로 조상의 변경사항을 가져온다.

=> merge 와 차이는 마지막 커밋 기록을 없앤 후, merge 후에 작성된 커밋 기록을 남긴다는 것이다.

 

관련 명령어

  • git merge <브랜치> : 해당 브랜치를 현재 브랜치에 병합한다.
  • git branch --merged : 병합된 브랜치들을 보여준다.
  • git fetch origin : 원격 레포지토리에서 최신 commit 코드를 임시 브랜치로 내려받고 merge는 하지 않는다. (merge를 따로 진행해 줘야함)
  • git pull origin <브랜치> : fetch 와 merge를 둘다 수행한다.
  • git rebase <브랜치> : 해당 브랜치에서 현재브랜치와 다른부분을 모두 내려받는다.
  • git rebase -i HEAD~1 <브랜치> : 해당 브랜치에서 가장 최근 HEAD로부터 바로 이전 커밋으로 돌아가 pick 또는 sqush를 진행한다.
  • git merge --abort : 충돌이 나거나 오류가 생겼을 경우 이 명령어를 통해 merge를 취소한다.

 

cf. git rebase --interative (-i) 옵션

과거 커밋 히스토리 수정을 대화형으로 실행할 수 있는 옵션이다.대체로 sqush를 하기위해 사용된다.
git rebase -i HEAD~3
해당 명령어를 사용하면 HEAD로부터 3번 전에 있는 커밋부분까지 포함된 vim 에디터가 나타난다.

 

  • pick : 해당 커밋을 수정하지 않고 그냥 사용하겠다는 뜻으로 커밋의 순서를 바꾸거나 삭제를 할 수 있다.
  • reword : 커밋 메시지를 수정할 수 있다.
  • edit : 해당 커밋의 작업내용까지 수정할 수 있다.
  • sqush, fixup : 해당 커밋을 이전 커밋과 합칠 수 있다. 대신 fixup은 이전 커밋 메시지만 남긴다.
  • exec, break, drop, merge  등 다양하게 사용가능하다.

 

cf. git rebase 중 충돌이 발생한다면?

충돌사항을 해결한 후
git add . -> git rebase --continue​

하면된다.

 

 

cf. git pull 과 git pull --rebase의 차이

"--rebase" 옵션은 Commit 이력을 한줄로 깔끔하게 관리 할 수 있다.
가장 큰 차이는
커밋기록을 전부 관리하느냐불필요한 이력은 정리하고 깔끔하게 커밋기록을 관리하느냐 (--rebase)
의 차이라고 볼 수 있다.

 

 

Git reset, revert & tag

reset (복귀, 되돌리기)

  • --soft : repo 에서 stage로 이동한다.
  • --mixed : repo 에서 WorkDirectory(M)로 이동한다.
  • --hard : repo 에서 수정전 상태(UM)로 초기화된다.
  • --merge : merge를 취소한다.

옵션을 붙이지 않을때는 --mixed가 생략되었다고 보면된다.

 

revert (commit을 남겨두고 되돌리기)

push 된 내역을 되돌리고 싶을 때 사용하면 된다.
reset 과 다르게 커밋을 삭제하는 것이 아니고 커밋을 추가한다.

 

tag

  • git tag : 모든 태그를 조회한다.
  • git tag -l <태그이름>* : 원하는 태그 필터링해서 조회한다.
  • git tag <태그이름> : 태그를 붙인다.
  • git tag -a <태그이름> : annotation 태그를 붙여준다.
  • git show <태그이름> : 해당 태그의 변경사항을 보여준다.
  • git checkout <태그이름> : 특정태그로 이동한다.
  • git push origin <태그이름> : 태그를 push한다.

 

annotated : 태그 + 정보 / lightweight : 태그 이름만

 

Git Flow & Github Actions

Git flow

git에서 제공하는 브랜칭 기능을 활용한 변경 이력 관리 전략이다.

  • main
  • develop
  • feature/
  • release/
  • hotfix/
  • support/

Github Actions

  • github에서 제공하는 CI/CD 도구
  • 소프트웨어 프로젝트의 자동화된 워크플로를 정의하고 실행 가능하게 함
  • 리포지토리 내에서 이벤트에 반응하여 자동으로 특정 작업을 실행하도록 설정할 수 있다.
  • 빌드, 테스트, 배포 등을 자동화 할 수 있다.

코어 개념

워크플로 (Workflow)

  • 정의 된 집합 워크플로는 YAML 형식으로 .github/workflows/ 폴더에 저장된다.

잡 (Job)

  • 하나 이상의 단계(Step)로 구성되며, Job은 독립적으로 실행되고 실행하는 환경도 설정할 수 있다.
  • 다양한 환경에서 실행할 수 있으며, ubuntu-latest, windows-latest, macos-latest 등의 운영체제에서 실행될 수 있다.

단계 (Step)

  • 각 단계는 하나의 작업을 수행하는 명령어이다.
  • 단계 내에서 쉘 스크립트 명령어를 실행하거나, github에서 제공하는 액션을 호출할 수 있다.

액션 (Action)

  • Github Actions 워크플로에서 실행할 수 있는 개별 작업이다. ex) 코드빌드, 테스트실행, AWS배포 등
  • github에서는 제공되는 액션뿐 아니라 사용자 만든 커스텀 액션도 가능하다.

이벤트 (Event)

  • 워크플로를 트리거 하는 조건이다.

Runner

  • Github Action Runner 어플리케이션이 설치된 머신으로, 워크플로가 실행될 인스턴스이다.

 

Fork & Pull Request

Fork

남의 원본저장소를 내 계정의 원격저장소로 복사하는 것이다.
협력자로 등록되지 않은 사람이 남의 원본 저장소에 푸쉬하려면 에러가 발생한다.

  설명 장점 단점
브랜치 하나의 원본저장소에서 분기를 나눔 하나의 원본저장소에서 코드 커밋 이력을 확인 가능 다수의 사용자가 다수의 브랜치를 만들면 관리하기 힘듦
포크 여러 원격저장소를 만들어 분기를 나눔 원본저장소에 영향을 미치지 않으므로 원격저장소에서 마음껏 수정 가능 원본저장소의 이력을 보려면 따로 주소 추가해야됨

Pull Request

협력자에게 브랜치 병합을 요청하는 메시지를 보내는 것이다.

 

 

★ 알아두면 좋은 리눅스 명령어

ls : 현재 디렉터리 파일 목록 표시
ls -a : 숨김파일까지 전부 표시
ls -l : 자세한 내용까지 전부 표시
ls -t : 정렬되어 표시 (최근수정된 파일 순)
ll : ls -al
cd .. : 이전 디렉토리로 이동
cd <폴더> : 해당 폴더로 이동
cd : 홈 디렉토리로 이동
mkdir <폴더명> : 폴더 생성
mv <이동할 파일> <이동할 위치> : 파일 이동
echo "내용" > <파일> : 해당 경로에 파일명 존재 할 경우 echo 출력 내용으로 새로운 파일 생성, 해당 경로에 파일명 미존재 할 경우 echo 출력 내용으로 파일을 덮어쓰기로 저장
echo "내용" >> <파일> : 해당 경로에 파일명 존재 할 경우 echo 출력 내용으로 새로운 파일 생성, 해당 경로에 파일명 미존재 할 경우 echo 출력 내용으로 파일을 이어쓰기로 저장
cat <파일.txt> : 텍스트 파일 내용을 화면에 출력
!cat : 가장 최근에 사용된 cat 명령어 실행
rm <파일> : 파일 제거
rm -r <파일> : 자식들까지 전부 제거
rm -rf <파일> : 강제 제거
cp <복사할 파일> <새로복사될파일> : 파일을 복사할때 사용
cp /dev/null > <파일> : 파일 내용 삭제
diff <비교파일1> <비교파일2> : 두 파일 사이의 내용을 비교 (오른쪽 기준으로)
history : 기존에 실행한 명령어 이력을 보여 주거나 실행할때 사용
history | grep "git push" : "git push" 와 관련된 명령어만 필터링
^<바꿀원래명령어>^ <새롭게 바꿀 명령어> : 최근 실행 명령어 중에 원래 명령어를 원하는 명령어로 바꿔서 실행 ex) ^vi^ source