📜 제목으로 보기

깃 기본 with vscode

extension 2개 설치

  1. git extension pack
  • git extension pack 검색후 설치
  • gitlens와 gitignore가 동시에 설치되어진다.
  • 왼쪽메뉴에 소스제어 를 클릭하면, gitlens가 통합되서 나온다. image-20210504205923102
  • 설정 > git enable이 활성화 되어있는지 확인한다.

  • gitlens layout 수정

    • gitlens를 왼쪽메뉴에 따로 보이게 되었는데, 설명서를 읽으니 gitlens.setViewsLayout 검색 > default로 클릭해야 source control탭에서 통합해서 볼 수 있다. image-20210505205146803
  • _git history는 팔레트에서 git log를 검색해서 사용
  1. markdown all in one

markdown all in one검색 후 설치

gitignore (팔레트커맨드)

  • add전에 설치된 gitignore를 사용하기 위해서ctrl+shift+p(모든 명령어, 팔레트)에서 gitignore를 검색하여, add ignore를 클릭
    • 이후 python 을 검색해서 선택 -> 파이썬을 제외시키는게 아니라 python관련 불필요 파일들이 등록이 된다.
    • create .gitignore가 생성되었다고 뜬다.
  • 소스제어에서, gitignore도 뜨는데, [파일열기]버튼이 따로 있다. image-20210504213410000

  • python프로젝트를 선택하더라도 .vscode/폴더를 맨끝에 추가해준다.

    • .vscode로 달아도 되지만, 폴더라서 마지막에 슬래쉬도 넣어준다.

    image-20210504214645218

add remote(팔레트커맨드)

  1. 빈repo를 생성

    • readme파일만 체크해서 생성( 첨부터 push안되게 충돌내기 위함. )
  2. > add remote 후 repo 선택

    • 주의 [remote name]: origin으로 기본적으로 설정한다!!!

    • 참고) add remote를 2개 했다면? git remote + remove [remote name]

  3. git config --list로 연결된 원격레포의 주소 확인하기

add, commit, and push in commits

  • U 파일들에서, +버튼을 눌러 add시키면, staging된 변경사항으로 이동한다.

  • commit은 상단의 [소스제어]에서 체크버튼으로 staging된 변경사항을 한번에 다 commit시킨다.

  • [commits] 탭 push를 클릭했다.

    • 해당 repo에서 push내역을 확인

    image-20211012224716917

pull(명령어) 및 이질적인 프로젝트 병합 허용(–allow-unrelated-histories)

git pull origin main
  • 현재 remote가 빈 레포가 아니므로, push가 바로 안됨

    • readme.md가 있기 때문에 pull당겨와서 충돌해결하고 해야함.

        fatal: refusing to merge unrelated histories
      
    • 이건 뭔짓을 하더라도 안됨. 따로 설정하면서 pull을 해줘야한다.

git pull origin main --allow-unrelated-histories

push

  • 갑자기 commits탭에서 사라져서.. 그냥

    • vscode 작업표시줄을 클릭하여 push

    • F1(팔레트)열고 git push검색해서 push

      해도 됨

    image-20211012225716315

[개념] branch (실무 많이)

  1. main은 항상 deploy상태로 유지
  2. topic branch = 수정용 브랜치 = push해서 PR하는 브랜치
    • push를 자주해서 날라가는 것을 방지하자.
    • 검토후 merged(PR)후에 바로 삭제하는 브랜치
  3. develop branch는 삭제안한다.
  4. main브랜치는 항상 최신으로 유지하므로 각 기능별 브랜치는 main에서 딴다. image-20210505003509762

[실습] branch(명령어)

image-20210505003749969

  • from-br없이 브랜치를 따면, 현재 브랜치에서 따는 것이므로 git branch명령어를 확인하고 따자.
    • git branch new-br from-br
    • git branch
      • git branch new-br
  • -로 직전브랜치를 checkout할 수 있다.

  • checkout -b [new-br] [from-br]로 생성하면서 동시에 브랜치를 변경하게 되므로 가장 자주 쓴다.

      git branch testbr main
      git branch
      * main
        testbr
        
      git checkout testbr
      Switched to branch 'testbr'
        
      git branch
        main
      * testbr
        
      git checkout - 
      Switched to branch 'main'
      Your branch is up to date with 'origin/main'.
        
      git branch
      * main
        testbr
          
      git checkout -b work main
      Switched to a new branch 'work'
        
      git branch
        main
        testbr
      * work
    

git merge 와 fastforwad

image-20211012235425670 image-20211012235500471 image-20211012235529831

  • merge commit은 서로 다른 상태의 브랜치를 병합해서 새로운 commit을 만드는 경우이고

    fast forward는 동일 내용이 포함되는 브랜치일 경우 브랜치 이동만으로 병합해서 따로 commit을 생성하지 않는 경우입니다.

topic branch(작업용브랜치) main에 merge후 삭제: git merge –no-ff / git branch -d

  • 현재 브런치 목록

        main
        testbr
      * work
        remotes/origin/main
    
  1. work를 토픽브랜치라 가정하고 파일 work.py생성 후 커밋

  2. main으로 돌아오면 당연히 파일이 없음.

  3. main에서 merge했다는 커밋을 남기면서(--no-ff) work브랜치를 받아오자.

    • 파일의 변화가 차이밖에 없는 경우. HEAD만 이동시키는 merge는 커밋이 발생안하고 앞으로 이동만 -> fast forward가 발생하는데, 여기서는 직접 merge 메세지도 남긴다.
     ❯ git merge --no-ff work
    
  4. merge의 log확인을 git history라는 익스텐션으로 해보자.

    • 나는 git graph라는 익스텐션도 보인다.

      image-20211014235222467

      • git history image-20211014235337124

      • git graph

        image-20211014235350860

      • git log –oneline –graph 의 명령어

        image-20211014235602708

  5. merge확인후 topic branch삭제

     ❯ git branch -d work
     Deleted branch work (was cbf2765).
    

git 탭에서 브랜치 변경후 개별커밋들 확인

image-20211015000149964

  1. 해당브랜치 화살표누르면 switch (checkout 됨)

  2. 왼쪽 화살표를 누르면, 각 브랜치마다 커밋 목록이 보인다.

    • 브랜치 생성이전 main브랜치 커밋이 그대로 보이는 듯함.

    image-20211015000405590 image-20211015000648926

  3. testbr에서만 파일 생성후 커밋해보자.

    • testbr이 위로 올라왔다.
      • branch 생성이후부터 달라진 커밋 차이가 난다. image-20211015001328774

[중요] topic branch에서 [다른topic이 merge된 main] 의 파일 1개만 받아오고 싶다면: git checkout -p

  • testbr에서 main속 work.py를 가져오고 싶다면

    • git checkout -p [가져올브랜치명] [가져올파일명]을 이용한다.
      • wsl2에서 안되서 windows 상태에서 하니깐 됬음.

​ 1. git checkout -p main work + y 로 main브랜치의 work.py를 가지고 온다.

❯  git checkout -p main work.py

diff --git b/work.py a/work.py
new file mode 100644
index 0000000..e69de29

(1/1) Apply addition to index and worktree [y,n,q,a,d,?]? y
  1. 현재 상태를 보면 add까진 된체 로 온다. image-20211015004734881
    • add전후 살펴보는 git status로 봐도, 이미 Add는 되어있다. image-20211015004808921 image-20211015005024857
  2. work.py에 내용을 조금 넣어주고 commit하자. image-20211015004904377

직전 commit의 메시지 변경: git commit –amend

  1. git commit --amend를 치면, 직전 commit에 대한 메세지 수정사항이 editor 로 열린다.
git commit --amend
  1. 메세지를 저장하면 자동으로 반영되어진다.

  2. 참고

    • 마지막 커밋A에 일부만 빠졌다?
      • 3을 빼고 1,2만 add 및 커밋한 상태
      • 3을 git add한 뒤 git commit --amend
    • 그냥 커밋메세지만 변경
      • git commit --amend -m "메세지"

HEAD포함 n번째[에] commit 합치기or삭제 등 commit history 조절: git rebase -i HEAD~[숫자] -> fixup or squash

  • HEAD~ = HEAD~1
    • HEAD포함 HEAD1개 전
      • ~1 = HEAD^ : 헤드의 부모, 헤드의 1개전
  • rebase는 명령어로 하는게 더 빠르고 쉽다.

image-20210505210227153

  • commit 1개당 1개의 의미를 가져야하나, 의미가 없는 커밋들을 하나로 합칠 때 , git rebase -i HEAD~ + [합칠 커밋갯수] 이후에
    • fixup: (귀찮아서) HEAD포함 n번째커밋에 커밋합치면서 n번째 커밋명으로 커밋합침
    • squash: (새로운커밋명을 위해) HEAD포함 n번째커밋에 커밋합치면서 + 새로운 커밋명으로 합침
    • 그외 reword(= amend), drop 등: 사용안한다.
  1. 커밋을 1111,222,3333333,4444,55555 5개를 새로 만들자 image-20211017013823583

  2. git rebase -i HEAD~[head포함 합칠 커밋갯수 & head에서 뒤로 2칸 간 곳에서 합쳐짐.]을 커맨드로 입력한다.

     ❯ git rebase -i HEAD~2
    

    image-20211017023334598

    • 여기서 커밋메시지 같은 git-rebase-todo 메세지에서 pick대신 fixup을 적어서 뭉개자.
      • 최근커밋인 5555(HEAD)를 fixup으로 뭉개서 저장시키면 된다. image-20211017023433229 image-20211017023443757

    따로 뭔가 뜨지 않으면 .git > rebase-merge > git-rebase-todo를 클릭한다. image-20211017020441390

  3. 도착지(HEAD포함 n번째 커밋)는 선택지가 없다.

    • 최근 것이며 뭉개지는 HEAD는 선택지가 있다.

      • 여기서 fixup을 선택하면, 귀찮게 새로운 커밋메세지를 작성안하고 n번째 커밋명을 이용하게 된다.

        image-20211017021919308 image-20211017022107109

      • start rebase를 해서 커밋을 합친다.

  4. 이제 444 ->333으로

     git rebase -i
    

    image-20211017023813902

    최근 것(아래 것)을 pick to squash로 변경해보자.

    • 과거커밋으로 합치는데 커밋메세지는 새로작성한다는 것이다.

      image-20211017023856342

    • 맨 위에 커밋메세지를 적으면 적용된다. image-20211017023934918 image-20211017023943718

이미해버린 commit 취소는 직전HEAD로 돌아가면서 취소: git reset –hard HEAD~

  • reset은 해당커밋까지가면서 자연스럽게 삭제한다.
  1. head의 부모로 가면서, head는 삭제 image-20211018014043041

     ❯ git reset --hard HEAD~HEAD is now at 3460720 Merge branch 'testbr' of https://github.com/is2js/git-ssac into testbr
    

    image-20211018014057536

add(staging) 취소는 아직commit안됬으므로 commit전 HEAD로 돌아가면서 취소: - or git reset HEAD

  • git extension으로 는 그냥 -버튼을 누르면 add가 취소됨 image-20210506233547359

  • 명령어로는 git reset HEAD로서

    • --hard없이 code를 살린체 최근HEAD로 돌아가면 -> add취소가 자동으로

    image-20211023000434343

      git reset HEAD # HEAD 대문자여야함.
    

    image-20211023000445814

깃 심화1 with vscode

###

  • git tag는 release의 의미를 가지므로 main에서 딴다.
    • tag
      • 혼자 = 커밋의 합 = 강의 n화
      • 협업 = topic -> main에서 merge후에 main에서 배포버전으로서 tag를 딴다.

merge는 항상 명령어로 –no-ff를 붙여 커밋을 남기자

  • --no-ff를 붙이면 fastfoward = 커밋없이 head위치만 바꾸는 것을 안하고 항상 merge커밋을 남긴다.
    • conflict나면, Accept incoming후 git commit만 입력해주면 메세지 완성되어있음.
  1. main브랜치로 넘어가기

  2. 명령어로 merge하기

     ❯ git merge --no-ff testbr
     Merge made by the 'recursive' strategy.
      hello.py  | 3 +++
      testbr.py | 0
      work.py   | 1 +
      3 files changed, 4 insertions(+)
      create mode 100644 testbr.py
    

merge후 topic branch는 삭제: git branch -d

  1. merge가 되었다면, topic 브랜치 삭제하기!!

     git branch -d testbr
        
     Deleted branch testbr (was 74296bb).
    
    • 만약, fully merge가 안되었다고 뜨면? 대문자 -D로 강제 삭제해준다.

        git branch -D testbr
      

tag 확인 및 생성 in main브랜치:git tag [v0.0.1]

  • tag는 release될 main브랜치에서 작성한다.
  • tag는 release단위 = 배포단위로 생성한다.
  • tag는 소스코드를 push를 해놓은 상태에서 -> tag를 local에서 따고 ->tag를 push한다.
❯ git tag

❯ git tag v0.0.1

❯ git tag

v0.0.1
(END)

tag는 commit과 별개로 따로 push: git push origin [tag(=버전)]

  1. git push origin [태그명=버전명]

     ❯ git push origin v0.0.1
     Total 0 (delta 0), reused 0 (delta 0)
     To https://github.com/is2js/git-ssac.git
      * [new tag]         v0.0.1 -> v0.0.1
    
  2. git repo에, tag가 생긴 것을 우측사이드에서 확인가능 image-20211019003006735

code수정 후 commit->push 끝난 뒤, 따로 tag 따고 -> push

  1. 파일(코드) 수정

  2. local git commit

  3. local -> origin(원격레포)로 push

     ❯ git add -A
     ❯ git commit -m "askldjflkasd"
     ❯ git push
    
  4. commit의 push가 끝난 뒤, tag를 딴다.

     ❯ git tag v0.0.2
     ❯ git push origin v0.0.2
     Total 0 (delta 0), reused 0 (delta 0)
     To https://github.com/is2js/git-ssac.git
      * [new tag]         v0.0.2 -> v0.0.2
    

tag는 과감하게 돌아가기: git reset –hard [태그]

  • git reset --hard [commit_hash]를 하면 해당 커밋까지 돌아가면서 자연스럽게 그 이후의 내용들은 삭제되었다.
    • 하지만, 태그의 경우, code + commit은 돌아가나 tag는 삭제안되고 남아있다.
❯ git reset --hard v0.0.1
HEAD is now at bd4c018 Merge branch 'testbr' into main


❯ git tag

v0.0.1
v0.0.2
  • 되돌아가도 tag는 남아있으니 직접 삭제해줘야한다.

reset tag이후에도 local+remote tag 따로 삭제: git tag -d 태그 / git push origin -d 태그

  1. 로컬 tag를 삭제한다.

     git tag -d v0.0.2
        
     Deleted tag 'v0.0.2' (was 476f70b)
    
  2. 원격에 남아있는 tag도 삭제한다.

     git push origin -d v0.0.2
        
     To https://github.com/is3js/py.git
      - [deleted]         v0.0.2
    

깃 심화2 with 개념위주

실수로 다른브랜치에 커밋or코드의존성때문에 다른사람 커밋이 필요할 때: git cherry-pick 으로 특정커밋만 똑! 가져올 때

image-20211011002343727

  • 코드의존성

    • 다른사람 커밋 위에서 일해야하는 경우
      • ex> 다른사람이 버그고침 -> 나는 그위에서 일을 해야할 때
  • master branch의 cccccccc커밋만 -> my branch로

    • 커밋해쉬 앞 7글자

        git cherry-pick ccccccc
      

      image-20211011002712243

git reset 총정리(add취소, commit취소)

  • ADD취소 2가지

    • 옵션을 안주면 mixed

    image-20211011003126389

  • 커밋취소 3가지

    • HEAD뒤에 눈웃음 한개 ^
      • --soft : commit만 취소 + add + 내용물 그대로
      • (mixed) : commt취소 + add취소 + 내용물만 그대로(unstaged)
      • --hard : commit취소 + add취소 + 내용물취소

    image-20211011003219453

HEAD와 ^, ~숫자

  • HEAD: 로컬 workingDir의 현재 작업중인 커밋
    • switch하면 작업폴더, 작업하는곳도 바뀌니 head도 바뀐다.
    • add만 했다면? 커밋이 아직 아니므로 HEAD가 보고 있진 않다.
  • HEAD^: 현재작업중 커밋의 부모커밋
    • ^^ : 부모의부모
    • ~3 : ^^^쓰지말고, 3단계 전 커밋 image-20211011004343131 image-20211011004351053 image-20211011004403666 image-20211011004429954

다시git reset HEAD 살펴보기with 돌아가서 자연스럽게 취소

  1. add 취소

    • 커밋이 아니므로, HEAD는 아직 안보고 있다.

    • 그래서 git reset HEAD를 하게 되면, HEAD커밋을 삭제하는게 아니라 git reset [여기] = [여기]로 돌아가겠다 = 해당커밋이후로 add는 커밋은 필요없다. 자연스럽게 add를 취소 image-20211011004613267

      image-20211011004726483 image-20211011004929115

  2. 커밋취소image-20211011005120724

    • git reset HEAD^ 현재의 부모커밋으로 가고 싶다.

    • 를 통해서 현재커밋을 취소

      image-20211011005133219

작업중에 다른작업요청시 commit도 reset도 애매한 임시저장: git stash

  • 로그인 브랜치에서 작업중인데, 갑자기 로그아웃 브랜치를 수정해달라고함.

    • 브랜치를 정리해야지만 브랜치변경이 가능함.
      • 커밋한다음 reset을 해도되긴하겠지만,,,
    • 커밋하기엔 미완성, 작업물을 날릴순 없다. 임시저장으로 정리
  • 현재 어느정도는 add된 상태

    • unstage된 = add되지 않는 파일도 있음.

      image-20211011005844708 image-20211011005931612

    • add, unstage 다 합쳐서 사진을 스태시! 하고 찍는다.

        git stash
      

      image-20211011010019725

      • 커밋이후의 상황들 전체가 stash 바구니에 담기게 됨.

        image-20211011010055227

    • 바구니에 담기면 사라진다. image-20211011010208956

  • git stash pop을 통해 stash바구니에서 꺼내면 다시 적용된다.

    image-20211011010245179

    • stack처럼 pop으로 나온다. image-20211011010324195 image-20211011010402997
  • git stash, git stash pop 이외에 git stash list도 있다. image-20211011010431876

마지막 커밋 변경(내용추가, 메세지변경): git commit –amend

image-20211011010616653

  • 마지막 커밋A에 일부만 빠졌다?
    • 3을 빼고 1,2만 add 및 커밋한 상태
    • 3을 git add한 뒤 git commit --amend
  • 그냥 커밋메세지만 변경
    • git commit --amend -m "메세지"

merge말고 1줄로 합치는데, 상대주는놈branch 위에 올려서 합칠 때:git rebase

  • 내 브랜치들을 주는놈branch 위에서 적용시키고 싶을 때

    • 최근브랜치가 내꺼가 되면서, 내가 주는놈 위에 적용됨.

    image-20211011011157120

    image-20211011011211637

  • 주의할점으로, 주는놈위에 쌓아올려질 때, 그대로 가는게 아니라 커밋해쉬가 달라짐 image-20211011011300333

merge vs rebase

image-20211011011440989

  • merge와 비교
    • 장점: 커밋해쉬 유지 및 흐름 유지되어 돌아갈 수 있음
    • 단점: merge라는 불필요커밋을 생성함.
  • rebase
    • 장점: 주는놈위에 받는놈위주로 정리가 됨. 깨끗한 커밋 히스토리가 됨.

커밋 합침, 삭제 등 커밋 히스토리 조절: git rebase -i

image-20211011011620097

pull받은이후 rebase로 커밋해쉬가 바뀌었다면? 어쩔수 없이 git push –force

image-20211011013551223

  • remote branch2개를 잘 받아왔다.

  • 이후 git rebase(주는놈위에 쌓아서 합침)로 내 커밋해쉬가 바뀌었다면?

    image-20211011013641088

    • 이 상태에서 git push하면 reject된다. image-20211011014624104
  • 어쩔수 없이 git push --force로 덮어씌워야함.

  • 협업중엔 조심해야한다.

    • 남자가 rebase후 푸쉬포스로 덮어씌워진다면,,

      image-20211011015657705 image-20211011015709288

    • 같은 브랜치 협업중에는 미리 말안하는 이상 rebase 및 push force를 하면 안될듯

alias

  • git push까지

    • status diff add cache? commit log
  • git폴더에

    image-20211011020355626

  • 내 환경설정에 image-20211011020850041

  • 참고

    • 히데쿠마 설정

        ## alias
              
        # git
        alias gst='git status'
        alias gc='git commit'
        alias gm='git merge'
        alias gr='git reset'
        alias ga='git add'
        alias gaa='git add --all'
        alias gloga='git log --oneline --decorate --color --graph --all'
        alias glog='git log --oneline --decorate --color --graph'
        alias gco='git checkout'
        alias gb='git branch'
        alias gcb='git branch | fzf -m | xargs git checkout'
        alias gmb='git branch | fzf -m | xargs git merge'
        alias gdb='git branch | fzf -m | xargs git branch -D'
        alias gp='git push'
        alias gf='git fetch'
        alias gl='git pull'
        alias gd='git diff'
        alias ghf='git ls-files -v | grep "^h" | cut -c3-'
              
              
        # dkr
        alias dkr='docker'
        alias dkrp='docker-compose'
        # for docker
        #sudo mount --bind /mnt/c /c
        sudo mount --bind /mnt/d /d
        export DOCKER_HOST=tcp://0.0.0.0:2375
              
        # basic
        alias dotfiles='cd ~/dotfiles'
        alias ll='ls -al'
        alias l='clear && ls -al'
        #alias cdd='cd /d/'
        alias ws='cd /d/workspace'
        #alias solup='cd /d/workspace/solup'
        alias echost='cd /d/workspace/solup/echost'
        alias 12r='cd /d/workspace/solup/12r'
        alias private='cd /d/workspace/private'
        alias ..='cd ..'
        alias ..2='.. && ..'
        alias ..3='..2 && ..'
              
        # some more ls aliases
        #alias ll='ls -alF'
        alias la='ls -A'
        #alias l='ls -CF'
              
        # Add an "alert" alias for long running commands.  Use like so:
        #   sleep 10; alert
        alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
              
              
        # for python
        alias python='python3'
        alias pip='pip3'
        export WORKON_HOME=~/.virtualenvs
        export VIRTUALENVWRAPPER_PYTHON='/usr/bin/python3'  # Usage of python3
        source ~/.local/bin/virtualenvwrapper.sh
        # for pyenv
        export PYENV_ROOT="$HOME/.pyenv"
        export PATH="$PYENV_ROOT/bin:$PATH"
        export PYTHON_CONFIGURE_OPTS="--enable-shared"
        export PYENV_VIRTUALENV_DISABLE_PROMPT=1
              
        if command -v pyenv 1>/dev/null 2>&1; then
          eval "$(pyenv init -)"
          eval "$(pyenv virtualenv-init -)"
        fi