git cli!

git

익숙하지 않은 git 명령어만 정리

branch, switch

# dev 브런치 생성
git branch dev

# stg 브런치 생성
git branch stg

# stg 브런치로 이동
git switch stg

# 모든 local branch, remote branch 출력
git branch -a
#   dev
#   main
# * stg
#   remotes/origin/HEAD -> origin/main
#   remotes/origin/main

# dev 브런치 삭제
git branch -d dev

switch 는 브랜치의 전환만을 위한 명령어.

git switch dev

checkout 은 branch 이외에도 사용되는 경우가 많아 branch 전환을 위해서는 switch 사용을 권장

checkout

checkout 이란 전환 이란 표현이 적용 가능한 모든 아이템에 적용 가능하다.

  • branch 전환
  • commit 전환
  • 특정파일/디렉토리의 전환
    • a 파일/디렉토리를 A브런지로부터 전환, 없다면 가져오고, 있다면 전환
# local dev 브런치로 전황
git checkout dev
# dev branch 로부터 dev.txt 가져오기/전환하기
git checkout dev -- dev.txt
# 해당 commit 로부터 main.txt 가져오기/전환하기
git checkout 417a0de -- main.txt
# 지금 어떤 branch 에 있든 상관없이 커밋 버전 이동
git checkout 417a0de

reset

잘못 올린 커밋 원격 리포지토리에서도 취소하기

git reset --hard "commit id"
# main 브런치에선 repository 가 보호되어있어 동작하지 않을 수 있음
git push -f
git reset --hard origin/master
git pull origin master

reflog

실수로 reset 한거 되돌리기

# 과거 commit 으로 강제 이동 및 push
git reset --hard 417a0de
git push -f

# 실수를 깨닫고 복원시작
# local 에서 참조변경기록 확인
git reflog
git reset --hard HEAD@{3}

local 에서만 관리하는 깃에대한 모든 참조변경기록 를 보관하고 있기 떄문에 이전 상태로 돌아갈 수 있음.

merge, rebase

https://gist.github.com/mitchellh/319019b1b8aac9110fcfb1862e0c97fb

모든작업이 main branch 로부터 충돌없이 업데이트된다면 문제는 발생하지 않는다.
하지만 branch 를 나누어 작업하다 보면 충돌은 생기게되고 이를 해결하고 병합하는 과정에서 merge commit 은 반드시 생기게된다.

merge 는 직관적이지만 추가적으로 commit 이 하나 더 생기게 된다.

main 과 dev branch 에 각각 dev.txt 을 생성후 각 브런치에서 수정 후 commit,
그리고 main branch 에서 dev branch 를 병합하면 아래와 같은 형태로 history 가 구성된다.

o---o---o---o---M    main branch
 \         /
  o---o---o          dev branch

rebase 의 경우 아래처럼 branch 를 한줄로 관리할 수 있게 한다.
물론 합치는 과정에서 충돌은 발생하게 되며 충돌을 수정하는 과정에서 dev branch 의 커밋들은 변경된다.

원본 상태:
a---b---c    main branch
 \
  A---B---C  dev branch

rebase 후:
a---b---c---A'---B'---C'  main branch
          (dev branch)

해당 과정때문에 과거에 등록된 commit 들이 변경된 뒤 다시 등록될 수 있다,
이럴경우 force push 를 해야하는데 해당 branch 를 사용하는 다른 사용자들의 혼란을 야기할 수 있다.
자신만 사용하는 branch 에만 사용하는것을 권장한다.

squash 로 commit 기록 통합

아래와 같이 Update 1, Update 2, Update 3 3 개의 커밋을 만들었을 때 rebase 를 통해 합칠 수 있다.

git log --pretty=oneline
# 2d6e68bfb07c20d010e892726b29f11926807840 (HEAD -> dev, origin/dev) Update 3
# cd58900aa0be9962f900c66887a8854db428dd68 update 2
# 50a116474edaf738f883f85d82a776f812fef0a5 update 1
# 39c0a0de0d41cd13dd615c8eaf56b2da55805bbf (origin/main, origin/HEAD, main) add dev.txt comment

head 에서 총 3개의 commit 을 합치기

git rebase -i HEAD~2

위 명령을 실행하면 아래와 같이 3개의 commit 에 대한 처리를 진행하는 vi 입력창이 출력된다.

pick 50a1164 update 1
pick cd58900 update 2
pick 2d6e68b Update 3

# Rebase 39c0a0d..2d6e68b onto 39c0a0d (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
git push origin +<branch-name>

아래와 같이 맨 위 commit 을 합치는 기준(pick)으로 두고 squash 진행

pick 50a1164 update 1
s cd58900 update 2
s 2d6e68b Update 3

해당 명령또한 마찬가지로 force push 를 통해 이미 remotecommit 을 변경할 수 있음으로 신중히 사용해야한다.

bisect

commit –amend

마지막 commit 에 변경된 파일추가 및 commit 수정하기

해당 명령또한 마찬가지로 force push 를 통해 이미 remotecommit 을 변경할 수 있음으로 신중히 사용해야한다.

기존 커밋에 수정된 파일을 밀어넣고 메세지를 수정할 수 있다.

touch test-for-amend.txt
git add test-for-amend.txt
git commit --amend
# vi 창이 출력되면 commit 메세지 수정과 함께 커핏

commit –soft

마지막 커밋을 취소하고 변경된 파일을 다시 stage 로 돌리고 싶을때 사용.

local commit 만 사용하길 권장.

git reset --soft 97b88eb
git reset --soft HEAD^

rm –cached 원격 저장소 파일 삭제

git rm --cached .idea/modules.xml
git rm --cached -r .idea/
git commit -m "Fixed untracked files"
// 원격 저장소(origin)에 push
git push origin master
find . -name .DS_Store -print0 xargs -0 git rm -f –ignore-unmatch

checkout

브랜치 전환, 파일체크아웃, head 변경 등에 사용되는 만능명령어

commit을 원하지 않은 파일을 rollback 하고싶을때 아래와 같이 사용

git checkout dev
git checkout -b new-dev # 새로운 branch 생성
git checkout 58f0ab9 # 특정 커밋으로 HEAD를 이동
git checkout {filename}

remote

새로운 remote git 주소를 추가해서 branch 가 추가된것처럼 사용할 수 있다.

git remote add demo https://gitlab.my.company.com/demo-repo
# * main
#   remotes/demo/main
#   remotes/origin/HEAD -> origin/main
#   remotes/origin/main

git fetch demo

git remote -v
# demo	https://gitlab.my.company.com/demo-repo (fetch)
# demo	https://gitlab.my.company.com/demo-repo (push)
# origin	https://kouzie.com/demo-repo2 (fetch)
# origin	https://kouzie.com/demo-repo2 (push)

git branch -a
# * main
#   remotes/demo/main
#   remotes/origin/HEAD -> origin/main

# 만약 demo/main 을 로컬에서 사용하고 싶다면 main branch 이름이 중복되기 때문에 local branch 를 추가생성해야함.
git switch -c demo-main demo/main


git merge <remote-name>/<branch-name> --allow-unrelated-histories
git rebase <remote-name>/<branch-name>

upstream

fork 한 프로젝트의 코드를 다른 위치에 원본 있는 프로젝트로부터 동기화해야 할 때 사용하는 명령어

git remote add upstream https://github.com/Kouzie/test-repo
git remote -v                                                     
# origin  https://gitlab.my.company.com/demo-group/test-repo (fetch)
# origin  https://gitlab.my.company.com/demo-group/test-repo (push)
# upstream        https://github.com/Kouzie/test-repo (fetch)
# upstream        https://github.com/Kouzie/test-repo (push)

git remote fetch # 원격 데이터 fetch
git merge upstream/main # upstream 의 main 으로부터 merge

git remote rm upstream # 로컬에 연결된 remote upstream 삭제

submodule

저장소 안에 또 다른 깃 저장소가 필요한 경우 사용.
하나의 Git 저장소 내에서 다른 Git 저장소를 서브디렉토리로 포함시키는 방법.

각 서브모듈은 독립된 Git 저장소로 관리되며, 상위 프로젝트와 별개로 버전 관리된다.

아래와 같이 3개의 repository 가 있을 때

git clone https://gitlab.my.company.com/test-group/root-module
git clone https://gitlab.my.company.com/test-group/sub-module-a
git clone https://gitlab.my.company.com/test-group/sub-module-b

root-module repositorysub-module repository 2개 를 submodule 로 삽입한다.

cd root-module
git submodule add https://gitlab.my.company.com/test-group/sub-module-a
git submodule add https://gitlab.my.company.com/test-group/sub-module-b

cat .gitmodules
# [submodule "sub-module-a"]
#   path = sub-module-a
#   url = https://gitlab.my.company.com/test-group/sub-module-a
# [submodule "sub-module-b"]
#   path = sub-module-b
#   url = https://gitlab.my.company.com/test-group/sub-module-b

image26

각 디렉토리에는 별도의 .git 파일이 존재하고 commit 버전을 기준으로 연결시키기 때문에 별도의 pull 처리를 해줘야 버전을 따라갈 수 있다.
또한 root repository 에서 어떤 commit 버전을 사용할지도 결정해줘야 한다.

처음 서브모듈이 있는 git repository 를 git clone 하였을 때 서브모듈이 모두 비어있는 상태이다.

아래 init, update 명령을 통해 초기화 해야 한다.

git submodule init   # 서브모듈 초기화
git submodule update # 서브모듈 업데이트

# 서브모듈의 하위 서브모듈까지 모두 업데이트
git submodule update --init --recursive

subtree

subtree는 하나의 Git 저장소 내에서 다른 Git 저장소의 내용을 특정 디렉토리로 병합하는 방법.
서브트리는 상위 프로젝트의 일부로 취급되며, 하나의 통합된 Git 기록을 가진다.

git clone https://gitlab.my.company.com/test-group/root-tree
git clone https://gitlab.my.company.com/test-group/sub-tree-a
git clone https://gitlab.my.company.com/test-group/sub-tree-b

git subtree add --prefix=sub-tree-a https://gitlab.my.company.com/test-group/sub-tree-a main

git fetch https://gitlab.my.company.com/test-group/sub-tree-a main
# warning: redirecting to https://gitlab.my.company.com/test-group/sub-tree-a.git/
# remote: Enumerating objects: 3, done.
# remote: Counting objects: 100% (3/3), done.
# remote: Compressing objects: 100% (2/2), done.
# remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
# Unpacking objects: 100% (3/3), 2.79 KiB | 570.00 KiB/s, done.
# From https://gitlab.my.company.com/test-group/sub-tree-a
#  * branch            main       -> FETCH_HEAD
# Added dir 'sub-tree-a'

ls
# README.md  sub-tree-a

subtree 는 기존 git 의 history 를 보존하면서 두 repository 를 합칠 수 있다.

git log
# 두 repository 의 로그가 모두 저장되어있는지 확인

subtree 에서 변경된 내용을 pull 해올 수 있고
root 에서 subtress 의 내용을 변경하고 push 할 수 있다.

git subtree pull --prefix=sub-tree-a https://gitlab.my.company.com/test-group/sub-tree-a main

# warning: redirecting to https://gitlab.my.company.com/test-group/sub-tree-a.git/
# remote: Enumerating objects: 4, done.
# remote: Counting objects: 100% (4/4), done.
# remote: Compressing objects: 100% (2/2), done.
# remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
# Unpacking objects: 100% (3/3), 258 bytes | 86.00 KiB/s, done.
# From https://gitlab.my.company.com/test-group/sub-tree-a
#  * branch            main       -> FETCH_HEAD
# Merge made by the 'ort' strategy.
#  sub-tree-a/testb.txt | 0
#  1 file changed, 0 insertions(+), 0 deletions(-)
#  create mode 100644 sub-tree-a/testb.txt
git add .
git commit -m "add test.txt at subtree"
# root main 에다 push
git push
# subtree 에다가 push
git subtree push --prefix=sub-tree-a https://gitlab.my.company.com/test-group/sub-tree-a main

git push using:  https://gitlab.my.company.com/test-group/sub-tree-a main
warning: redirecting to https://gitlab.my.company.com/test-group/sub-tree-a.git/
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 260 bytes | 260.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0), pack-reused 0
To https://gitlab.my.company.com/test-group/sub-tree-a
   373ffb7..c76ee34  c76ee34422e3dcb9ecfcbe9c60bf9f7bdb3d08cc -> main

추가 옵션

subtree로 사용할 원격 저장소 추가

# git remote add <원격 저장소의 이름> <원격 저장소의 주소>
git remote add demo-lib https://gitlab.my.company.com/test-group/demo-lib

# demo-lib 라는 이름으로 새로운 원격 저장소가 추가되었다.
git remote
# origin
# demo-lib

새로운 원격 저장소의 브랜치를 서브트리로 추가

# git subtree add --prefix <클론할 폴더> <원격 저장소의 이름> <브랜치 이름>
git subtree add -P src/demo-lib https://gitlab.my.company.com/test-group/demo-lib main

.gitignore

깃허브에 올리지 말아야할 정보(OS, IDE 시스템정보 등)를 git 에 올리는 것을 방지,

대다수의 IDE 가 프로젝트 생성시 알아서 .gitignore 파일을 만들어 주지만
특수한 상황에서 직접 .gitignore 만들어야 할 때 아래 사이트 추천

https://www.gitignore.io/ image26

위와같이 현재 사용중인 시스템 정보를 삽입하면 아래와 같은 설정이 자동으로 생성된다.

# Created by https://www.gitignore.io/api/git,java,maven,windows,eclipse
# Edit at https://www.gitignore.io/?templates=git,java,maven,windows,eclipse

### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders

# sbteclipse plugin
.target

# Tern plugin
.tern-project

# TeXlipse plugin
.texlipse

# STS (Spring Tool Suite)
.springBeans
...
...

이파일 내용을 .gitignore 파일로 저장

config

git config –global http.sslVerify false

카테고리:

업데이트: