git-study's Introduction
git-study's People
git-study's Issues
Detached HEAD란?
Attached HEAD
Detached HEAD가 있다면, Attached HEAD는 무엇일까?
HEAD -> branch -> specific commit
을 가리키는 상태를 Attached HEAD
라고 한다.
Detached HEAD
Detached HEAD란 HEAD가 브랜치를 통해 commit을 가리키지 않고, 직접 커밋을 가리키는 것을 말한다.
HEAD가 다른 브랜치로 체크아웃했을 때, 이전 HEAD가 Detached HEAD였다고 하자.
이럴 경우, 해당 커밋의 revision number를 모르면 그 전으로 쉽게 돌아갈 수 없고, 그래프에도 표시되지 않는다.
아래 명령어를 사용하면 detached HEAD상태가 된다.
git checkout master^
git checkout HEAD~2
git checkout origin/master
git checkout <tag name>
git checkout <revision number>
detached HEAD의 상태로 만들기
HEAD가 바로 이전 커밋을 가리키게 하여, detached head 상태로 만들어보자.
git checkout HEAD~1
gloga
로 확인해본 브랜치와 HEAD와 커밋의 관계이다.
HEAD가 직접 커밋을 가리키는 detached head상태가 된 것을 확인할 수 있다.
그리고 이 상태가 되면, git도 내가 어떤 상태인지 알려준다.
Attached HEAD 상태였던 커밋으로 돌아가면 될까?
다시 attached HEAD상태로 만들려면, HEAD가 attached HEAD였던 커밋으로 돌아가면 되지 않을까?
git reflog
로 내가 돌아가고 싶은 커밋을 확인하고, 이전 커밋으로 돌아가보자
git reflog는 이전 커밋 내역을 보여주는 명령어다.
3f679ed
은 HEAD를 detached head로 만들었던 커밋이다. 바로 이전 커밋으로 돌아가면 attached HEAD가 될까?
HEAD를 master와 branch-a가 있는 8bf981f
로 이동시키자.
git checkout 8bf981f
안타깝게도 여전히 detached head상태이다. HEAD가 브랜치를 통해 커밋을 가리키지 않고, 직접 커밋을 가리키고 있다.
깃은 브랜치를 통해 커밋들을 관리한다. detached HEAD commit은 브랜치에 연결되어있지 않아서 관리가 안되어서 문제이다.
어떻게 Attached HEAD의 상태로 만들까?
방법은 브랜치를 새롭게 만드는 것이다.
git checkout -b <branch name>
브랜치의 상태를 확인해보면, HEAD가 now-in-attached
브랜치를 가리키고, now-in-attached
브랜치는 커밋을 가리키는 attached HEAD
상태가 된 것을 알 수 있다.
출처
branch base가 잘못되었다니...?!
처음으로 맡은 일을 처리하고 PR을 남기려던 찰나에,
내가 따온 브랜치가 아닌 다른 브랜치에서 브랜치를 따왔어야함을 알게 되었다... 😳
원래 팠어야 하는 브랜치에서 다시 작업을 해야하나...?
고민하던 중에 팀원분께서 cherry-pick
을 이용해보라고 하셨다.
cherry-pick이란 다른 브랜치에서 원하는 커밋을 내 브랜치로 가져올 때 사용하는 명령어이다.
branch base를 찾기 위해 여러 블로그를 돌아다니면서 해보았다.
그 여정을 커밋 이력을 살펴보면서 다시 알아봐야겠다.
- 브랜치 이름 정의
- feature : 내가 작업했던 브랜치
- base : 원래 따왔어야 하는 올바른 브랜치
1. rebase
로 commit message 바꾸기
우선 내가 작성한 커밋 메시지가 커밋 컨벤션에 어긋나있음을 확인했다.
커밋 메시지를 수정을 git rebase
로 하였다.
git rebase -i HEAD~6
HEAD부터 이전 몇 번째 커밋까지 수정할 것인지를 적어주었다.
그러면 내 커밋 이력이 있는 vim 창이 뜬다.
pick 8cc09ef9 Fix: ...
pick 5e355c52 Markup: 이미지 변경
pick 4d0902de Markup: 이미지 변경
pick fc8cb382 Update: [프론트]
pick 4edee528 Update: [프론트]
pick 7a339cc4 Update: [프론트]
# Rebase 542daaf8..67bd2376 onto 4d0902de (19 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 <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
여기서 pick
을 reword
혹은 r
로 바꿔주고, :wq
로 저장하고 창을 나간다.
이후 차례로 커밋 이력을 수정할 수 있는 창이 뜨게 된다.
커밋 메시지를 수정후, 저장해준다.
수정한 커밋 메시지가 잘 반영되었는지를 git log
로 확인하자.
2. 작업한 커밋을 원격 origin 레포의 feature로 푸쉬 -> 실패
커밋이 잘 수정되었으니, 이를 origin 레포에 우선 올려두고자 하였다. (로컬에 있다가는 못찾을까봐 무서워서...)
그래서 feature 브랜치로 푸쉬하였으나 실패하였다.
그 때 떴던 경고가 Detached HEAD
라는 것이었다.
HEAD가 브랜치를 가리키지 않고, 커밋을 직접 가리키는 것을 말한다.
이를 해결하기 위해 Attached HEAD로 바꾸는 작업을 진행했다.
3. Detached HEAD를 Attached HEAD로 바꾸기
전략은 이러하다.
커밋 2a0c62cf
은 수정된 커밋 메시지의 기록이 있는 가장 마지막 커밋이다.
- 이 커밋을 기준으로 branch
temp
를 만들고, 기존 feature 브랜치는 삭제한다.
git branch temp 2a0c62cf
git branch -D feature
- temp 브랜치의 이름을 feature로 바꾼다.
gb -m temp feature
4. 작업한 커밋을 원격 origin 레포의 feature로 푸쉬 -> 성공
feature를 다시 원격 feature 브랜치에 푸쉬한다.
git push origin feature --force
5. cherry-pick으로 base
브랜치에 있는 커밋 가져오기
내 feature브랜치에는 없고, base 브랜치에는 있는 커밋을 알아낸 후,
해당 커밋들을 내 브랜치로 가져오고자 하였다.
git log feature..base --oneline --no-merges
여기서 보여지는 커밋 이력중 가장 첫 커밋 ~ 가장 마지막 커밋을 체리픽을 가져오고자 했다.
git cherry-pick <commit-A>^..<commit-B>
은 commitA부터 commitB까지의 커밋을 checkout된 브랜치로 가져오게 된다.
git cherry-pick 28791afc^..a0818146
그랬더니 다음과 같은 에러가 뜨면서 체리픽은 실패했다고 알려주었다.
error: empty commit set passed
fatal: cherry-pick failed
base 브랜치가 내가 따왔던 브랜치와 합친 상태여서, base와 내 브랜치에서 충돌은 없었다.
그래서 어제는 일단 PR을 날리고 마무리를 했다.
💡 오늘 다시 와서 생각해보니, base 브랜치에서 새로운 브랜치를 만들고,
그 브랜치에서 내가 작업했던 커밋들을 cherry-pick했어야 하는 것 같다...!
git에 대해 잘 모르니까 시간 너무 잡아먹는다. git 어렵지 않게 사용할 수 있도록, git 공부도 해야겠다.
참고
폴더마다 config 다르게 두기
😑 뭐가 문제였냐면...
회사 레포지토리는 ~/kakao에 두고 있고, 개인 레포지토리는 ~/study에 두고 있다.
global config는 회사 계정이다.
/study 폴더에 개인 레포지토리를 만들어서 커밋할 때마다 계정이 회사 계정으로 등록되었다.
매 번 개인 레포를 만들때마다 local 설정을 해야했지만, 설정해주는걸 까먹은 적도 있고...넘 귀찮고...
그래서, /study 폴더에 있는 레포지토리는 다른 config 파일을 사용하게 하고 싶었다.
😎 그래서 이렇게 하니까...
.gitconfig
파일에 디렉토리 경로에 study
가 포함되어있다면 .gitconfig-study
설정 파일을 참고하도록 하였다.
- ~/.gitconfig
[user]
name = lillie.yang
email = [email protected]
[includeIf "gitdir:~/study/"]
path = ~/.gitconfig-study
...
- ~/.gitconfig-study
[user]
name=yejineee
[email protected]
😏 뭐가 좋았냐면~
이렇게하면 따로 레포지토리마다 local 설정을 하지 않아도, study 폴더에 있는 레포지토리들은 전부 개인 계정으로 설정이 된다. 👍
참고
git branch 여러개 삭제하기
Local 브랜치 패턴으로 찾고, 삭제하기
$ git branch | grep {pattern} | xargs git branch -D
xargs
는 pipeline 해주는 명령어이다. 이전의 결과를 다음의 입력으로 넣어준다.
원격저장소의 브랜치 가져오기
git remote 갱신하기
git remote update
원격 저장소 branch 확인
-
원격 저장소의 브랜치 리스트
git branch -r
-
로컬, 원격의 모든 브랜치 리스트
git branch -a
원격 저장소의 branch 가져오기
git checkout -t <branch name>
예 : git checkout -t origin/sysprog
- 이름 변경해서 가져오기
git checkout -b <생성할 브랜치 이름> <원격 저장소의 브랜치 이름>
원격 브랜치 참고하기
git checkout <branch name>
아무런 옵션없이 checkout하면 'detached HEAD' 상태로 소스를 확인, 변경할 수 있다.
그러나, commit push할 수 없으며, 다른 브랜치로 체크아웃시 사라진다.
HEAD란 무엇인가?
HEAD
브랜치가 master, branch-a가 있는데, 이중 작업중인 브랜치를 아는 방법은 무엇일까?
git은 'HEAD'
라는 포인터를 갖고 있다. 이 포인터가 지금 작업하는 로컬 브랜치를 가리킨다.
git log —oneline —decorate
git log --oneline --decorate
를 사용하면, 브랜치가 어떤 커밋을 가리키는지 확인할 수 있다.
현재 브랜치는 HEAD가 가리키는 branch-a이다.
master와 branch-a 둘 다 840f217을 가리키는 것을 확인할 수 있다.
-
팁 :
gloga
zsh는gloga
라는 alias를 제공하는데, 이는git log --oneline --decorate --graph --all
이다.간단하게
gloga
로 현재 브랜치가 어떤 커밋을 가리키는지 확인하자!
참고
Git 구조
git stash로 작업중이던 파일을 임시 저장하기
git stash란?
- 커밋은 할 수 없지만, 브랜치 전환을 하거나 커밋 변경을 해야할 때, 작업하던 내용을 스택에 넣을 수 있다.
사용법
stash 영역에 추가하기
git stash
: 트래킹된 파일을 저장.WIP
로 저장됨.git stash save [이름]
: stash한 작업에 이름을 저장
stash 영역에서 꺼내기
git stash apply
: 가장 최근에 저장한 stash를 복원. list에 남아있다.git stash apply [stash id]
: stash id에 해당하는 stash를 복원git stash pop
: 가장 최근에 저장된 stash를 복원하고, list에서 삭제
stash 영역 조회하기
git stash list
: stash 기록을 리스트로 확인
commit message 수정하기
rebase로 commit message 바꾸기
커밋 메시지를 수정을 git rebase
로 하였다.
git rebase -i HEAD~6
HEAD부터 이전 몇 번째 커밋까지 수정할 것인지를 적어주었다.
그러면 내 커밋 이력이 있는 vim 창이 뜬다.
pick 8cc09ef9 Fix: ...
pick 5e355c52 Markup: 이미지 변경
pick 4d0902de Markup: 이미지 변경
pick fc8cb382 Update: [프론트]
pick 4edee528 Update: [프론트]
pick 7a339cc4 Update: [프론트]
# Rebase 542daaf8..67bd2376 onto 4d0902de (19 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 <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
여기서 pick
을 reword
혹은 r
로 바꿔주고, :wq
로 저장하고 창을 나간다.
이후 차례로 커밋 이력을 수정할 수 있는 창이 뜨게 된다.
커밋 메시지를 수정후, 저장해준다.
수정한 커밋 메시지가 잘 반영되었는지를 git log
로 확인하자.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.