백준 온라인 저지 시스템의 코드와 리팩토링 과정, 공부 내용을 깃헙에 업로드 하기 위해 새로운 프로젝트를 생성하고 VCS로 Git을 지정했다. src 패키지 아래 알고리즘 분류 또는 단계별 분류로 패키지를 생성하고 그 하부에 각 문제별 패키지를 생성하여 README.md 에는 문제와 테스트 케이스를 기재하고 코드별 클래스 파일을 담았다. src 패키지에서 초록 글씨로 표시되는 부분은 현재 git에서 추적하고 있는 파일이고 빨간 글씨로 표시되는 부분은 추적하지 않는 파일이다.
# 현재 git이 추적하고 있는 파일 목록
git ls-files
# 출력 내용 : 위 스크린샷과 같다.
Dev-Hammy@treadmill:~/IdeaProjects/baekjoon$ git ls-files
.gitignore
.idea/.gitignore
.idea/misc.xml
.idea/modules.xml
.idea/uiDesigner.xml
.idea/vcs.xml
baekjoon.iml
src/DynamicProgramming/P_1463/P_1463.java
src/DynamicProgramming/P_1463/README.md
윈도우 상단에는 현재 브랜치의 위치가 'P_2839'로 나타난다. git branch
로 확인하면 현재 위치한 브랜치 이름 앞에 *
표시가 나타난다.
# 현재 사용 중인 브랜치
git branch
# 출력 내용 : 현재 위치한 브랜치 이름 앞에 * 표시
Dev-Hammy@treadmill:~/IdeaProjects/baekjoon$ git branch
DynamicProgramming
P_1463
* P_2839
main
인텔리제이 윈도우 하단에는 Git 전용 패널도 존재한다. Log
패널에서 Branch
등을 확인할 수 있고 Console
에서 실행내역을 확인할 수 있다.
# 모든 브랜치 확인
git branch -a
# 새 브랜치 생성하고 그 브랜치로 전환
git checkout -b <브랜치 이름>
로컬 디렉토리 구조를 따라서 git checkout -b DynamicProgramming
으로 부모 브랜치를 생성한 다음, 자식 브랜치로 P_2839, P_1436을 생성하려고 한다. git checkout -b P_2839
로 자식 브랜치를 생성한다.
p_1436
은 하단의 Git Log 패널에서 DynamicProgramming 브랜치를 선택 후 마우스 우측 버튼을 클릭하여 New Branch from DynamicProgramming
으로 생성하였다.
git reflog show --all | head -n 1
# 출력 내용
3e129d6 refs/heads/P_1463@{0}: branch: Created from DynamicProgramming^0
git reflog
: git reflog 명령어는 HEAD 위치의 변경 내역을 보여줍니다.
show
: git reflog
명령어에 사용되는 옵션으로, reflog 항목을 표시합니다.
--all
: show
옵션과 함께 사용되며, 모든 reflog 항목을 표시합니다.
|
: 파이프라인(pipe) 기호로, 왼쪽 명령어의 출력을 오른쪽 명령어의 입력으로 전달합니다.
head -n 1
: head
명령어는 텍스트 데이터의 처음 몇 줄을 보여주는 명령어입니다. -n 1
은 처음 1줄만 표시하라는 옵션입니다. 따라서 이 부분은 reflog의 처음 1개 항목만 표시하라는 의미입니다.
git reflog show --all | head -n 1
명령의 출력 결과에 따르면 현재 헤드가 위치한 브랜치는 P_1436이며 이 브랜치는 DynamicProgramming 브랜치로부터 생성되었다.
https://copyprogramming.com/howto/how-to-get-git-parent-branch-name-from-current-branch
# 현재 HEAD 위치를 확인
git symbolic-ref --short HEAD
# 현재 HEAD 위치가 위치한 브랜치를 확인
# 만약 HEAD가 직접 커밋을 가리키고 있다면, "HEAD detached at"과 함께 현재 커밋의 해시값이 표시됩니다.
git rev-parse --abbrev-ref HEAD
# 현재 위치한 브랜치의 부모 자식 관계를 확인
git show-branch --current
챗 지피티 말로는 !
표시된 것들은 모두 현재 브랜치의 상위 브랜치라고 한다. rebase
를 위해 사전 작업을 진행한다.
git status
git status
명령은 현재 브랜치, 스테이징 영역, 작업 디렉토리의 변경 사항을 보여줍니다. 스테이징되지 않은 변경 사항은 "변경됨" 또는 "추적되지 않음"으로 표시됩니다.
패키지 별로 작업 내용도 분리하고 싶기 때문에 git restore --staged <file>
명령을 사용한다.
# 현재 브랜치에 staged 된 작업 내역 삭제
git restore --staged <file>
# 새로 생성한 파일은 제외하고 수정/삭제한 내역만 추가
git add -u
# 프롬프트를 띄워 add 할 내용 선택하기
git add -p
git commit
# commit 메시지를 편집할 수 있는 편집기가 나타나고 그 내용을 저장하면 아래와 같이 맨 첫줄의 내용이 보입니다.
[P_2839 573de30] [feat] (DynammicProgramming/P_2839) Implement Package
3 files changed, 69 insertions(+), 71 deletions(-)
create mode 100644 src/DynamicProgramming/P_2839/P_2839_1.java
create mode 100644 src/DynamicProgramming/P_2839/README.md
delete mode 100644 src/by_Type_DynmaicProgramming/P_2839.java
# DynamicProgramming 브랜치에 리베이스
git rebase DynamicProgramming
위 스크린샷은 현재 브랜치가 P_2839일 때 아래 스크린샷은 현재 브랜치가 DynamicProgramming일 때이다.
git checkout <변경사항 커밋이 완료된 하위 브랜치의 상위 브랜치>
git merge <상위 브랜치에 붙일 하위 브랜치>
P_2839 브랜치의 내용이 DynamicProgramming 브랜치에 merge되어 같은 구조를 가지게 됐다.
P_1436 브랜치는 DynamicProgramming 브랜치로부터 created 되었지만, 변경사항이 자동으로 반영되지는 않았다. git add <파일경로지정>
로 DynamicProgramming/P_1463 내부의 파일을 모두 stage 영역에 추가한다. git commit
을 실행하여 커밋 메시지를 작성 및 저장하고 git log
로 현재 브랜치의 커밋 내역을 확인한다.
# 현재 브랜치 커밋 내역 확인
git log
# q 를 누르면 밖으로 나가짐
P_2839의 커밋 메시지에서 스코프를 표시했듯이 P_1436의 커밋메시지를 수정하려고 한다. git commit --amend
명령으로 수정한 커밋은 이전 커밋과 다른 SHA-1 해시 값을 가지므로 주의가 필요하다. 수정된 커밋은 이미 리모트 저장소로 푸시한 경우에는 사용하지 않는 것이 좋다.
# 기존 커밋 메시지 내용 수정
git commit --amend
커밋 메시지가 수정되면서 c0674
로 시작하던 마지막 커밋의 해시코드가 6a876
으로 시작하는 해시코드로 변경되었다.
P1436 브랜치에는 'by_Type'으로 시작하는 패키지가 추적목록에 올라와 있었는데 이것을 제외한 나머지 커밋들만 반영하고 싶어서 git cherry-pick
을 사용했다.
# 다른 브랜치의 커밋 목록을 보고 싶다면
git log <다른 브랜치 이름>
# 현재 브랜치에 추가하고자 하는 커밋의 해시코드를 이용
git cherry-pick <커밋 해시코드>
의도한 대로 작업이 수행되었다.
# merge 실행 전
--- A --- B --- C (feature-branch)
\
D --- E (main)
# merge 실행 후
--- A --- B --- C --- F (feature-branch)
\ /
D --- E (main)
# rebase 실행 전
--- A --- B --- C (feature-branch)
\
D --- E (main)
# rebase 실행 후
--- A --- D --- E --- B --- C (feature-branch)
/
(main)
# cherry-pick 실행 전
--- A --- B --- C (main)
\
D (feature-branch)
# cherry-pick 실행 후
--- A --- B --- C --- D' (main)