#title Git & Tips [[TableOfContents]] === 일반 === ==== 알아두면 좋은 기능 ==== ===== alias g='git' ===== 예) .bashrc 에 alias 기록 alias gs='git status -s' alias gp='git pull' ===== stashing ===== 현재 브랜치에서 작업중인 내용을 임시로 저장하고 다른 브랜치로 이동할 때 사용한다. ===== blame ===== 파일 라인 단위로 누가 마지막으로 수정했는지 보여준다. http://git-scm.com/docs/git-blame ==== 작업의 취소 ==== http://www.evernote.com/l/AMKuBFPL-uZItrAAGvEbqooTf52dvpkR1rQ/ ==== push의 취소 ==== http://whiteship.me/?p=13516 === commit === ==== commit 메시지 수정 ==== ===== 마지막 커밋을 수정하기 ===== [[Code($ git commit --amend)]] 마지막 커밋을 수정하는 방법은 매우 간단하다. 이 명령으로 텍스트 편집기가 열리고 메시지를 수정하면 된다. ===== 커밋 메시지를 여러 개 수정하기 ===== 예를 들어 마지막 세 번째에 있는 커밋 로그를 수정하고 싶다면 rebase -i를 사용해서 수정한다. 주의할 점은 이미 서버에 push된 커밋은 SHA-1 값이 바뀌기 때문에 가능하면 수정하지 말아야 한다. 만약 rebase에 익숙하지 않다면 다음을 주의 깊게 봐야 한다. https://git-scm.com/book/ko/v1/Git-%EB%8F%84%EA%B5%AC-%ED%9E%88%EC%8A%A4%ED%86%A0%EB%A6%AC-%EB%8B%A8%EC%9E%A5%ED%95%98%EA%B8%B0 [[Code($ git rebase -i HEAD~3)]] 텍스트 편집기가 열리면 다음 같은 커밋 목록이 첨부되어 있다. {{{ pick ... pick ... pick ... }}} 여기서 커밋 목록 순서는 위쪽이 오래된 것이다. 마지막 세 번째 커밋 메시지를 수정하려면 pick을 edit로 변경하고 저장 및 종료한다. {{{ edit ... pick ... pick ... }}} 저장하고 편집기를 종료하면 Git은 목록에 있는 커밋 중에서 가장 오래된 커밋으로 이동하고, 아래와 같이 다음은 어떻게 해야 하는지 메시지를 보여준다. {{{ $ git rebase -i HEAD~3 Stopped at 7482e0d... updated the gemspec to hopefully work better You can amend the commit now, with git commit --amend Once you’re satisfied with your changes, run git rebase --continue }}} 마지막 커밋 메시지를 변경했을 때와 같이 [[code(git commit --amend)]] 으로 메시지를 변경하고 [[code(git rebase --continue)]]로 rebase를 계속한다. 이것을 반복하면 어떤 위치의 커밋 메시지도 수정할 수 있다. 다시 말하지만 주의할 점은 이미 서버에 push된 커밋은 rebase를 하면 SHA-1 값이 바뀌기 때문에 동료 개발자들을 혼란스럽게 할 가능성이 있다. 될 수 있으면 수정하지 말아야 한다. === log === ==== 커밋 범위 지정하여 로그 보기 ==== [[code(git log START_COMMIT..END_COMMIT)]] [[code(ex) git log ea87e9..60a6da)]] ==== 특정 날짜 이전/이후 commit만 출력 ==== [[code(git log --since[after,until,before])]] [[code(ex) git log --before="2018-07-15")]] ==== 개수 출력 ==== [[code(git log -2)]] 2개만 출력 ==== commit 메시지의 첫 번째 줄만 출력 ==== [[code(git log --pretty=short)]] ==== 파일의 변경된 내용을 출력 ==== [[code(git log -p)]] ==== 브랜치를 시각적으로 출력 ==== [[code(git log --graph)]] === branch === ==== 브랜치 확인 ==== 현재 브랜치 [[code(git branch)]] 모든 브랜치 [[code(git branch -a)]] ==== 브랜치를 만들고 변경 ==== 예) hotfix-A 브랜치로 변경 [[code(git checkout -b hotfix-A)]] [[code(checkout -b)]]는 [[code(git branch hotfix-A)]] 브랜치를 만들고, [[code(git branch checkout hotfix-A)]] hotfix-A 브랜치로 이동하는 것과 동일함. ==== 브랜치 제거 ==== [[code(git branch -D hotfix-A)]] === merge === ==== 브랜치, commit id 머지 ==== 예) 머지 대상 브랜치: master 머지 브랜치: hotfix [[code(git checkout master)]] [[code(git merge --no-ff hotfix)]] 예) 머지 대상 브랜치: master 머지 commit id: c1234bbbc [[code(git checkout master)]] [[code(git merge --no-ff c1234bbbc)]] [[code(--no-ff)]] The --no-ff flag prevents git merge from executing a "fast-forward" if it detects that your current HEAD is an ancestor of the commit you're trying to merge. ==== 머지 conflict 해결 ==== 예) 1. 충돌 발생 {{{ <<<<<<< HEAD ... ======= ... >>>>>>> hotfix-A }}} 2. ===, <<<, >>> 표시를 확인하면서 충돌문제를 해결한 후 저장한다. IDE에서 Git 기능을 제공한다면 충돌 해소에 IDE 도움을 받을 수 있는 경우가 많다. 3. 문제를 해결하고 commit 한다. [[code(git commit -m 'Fix conflict')]] 4. 다시 merge 한다. ==== prevents the MERGE COMMIT to occur ==== [[code(git merge --no-commit)]] [[code(--no-ff)]] 와 같이 사용. [[code(git merge --no-ff --no-commit)]] ==== 머지 취소 ==== [[code(git merge --abort)]] 머지 수행 전 상태로 돌아간다. === stash === ==== 기본 명령 ==== * 현재 작업 상태 stash 저장하기 {{{ $ git stash }}} * 저장된 stash 확인 {{{ $ git stash list }}} * 저장된 stash 적용하고 제거 {{{ $ git stash pop }}} * 저장된 stash 적용하고 제거하지 않음 {{{ $ git stash apply }}} * 특정 stash만 제거할 때 {{{ $ git stash list stash@{0}: WIP on master: 049d078 added the index file stash@{1}: WIP on master: c264051 Revert "added file_size" stash@{2}: WIP on master: 21d80a5 added number to log $ git stash drop stash@{0} Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) }}} ==== How can I delete all of my Git stashes at once? ==== It does what you need: {{{ $ git stash clear }}} from [http://www.kernel.org/pub/software/scm/git/docs/git-stash.html git documentation] === patch === ==== 생성 ==== {{{ git diff > patchfile # 패치파일 생성 }}} {{{ git diff --no-prefix > patchfile # 패치파일 생성 }}} ==== 적용 ==== --no-prefix 옵션 없이 패치파일 생성한 경우 -p1 (diff의 a/ b/ path prefix 무시) {{{ cd path/to/top # 패치하고자 하는 소스 위치 patch -p1 < patchfile # 패치 적용 }}} {{{ cd path/to/top # 패치하고자 하는 소스 위치 patch -p0 < patchfile # 패치 적용 }}} === config === ==== git config 순서 및 위치 ==== {{{ $ git config --system ## /etc/gitconfig $ git config --global ## ~/.gitconfig $ git config --local ## repo/.gitconfig }}} 각 설정 파일에 중복된 설정이 있으면 system부터 순서대로 덮어 씌운다. 즉, git은 가장 먼저 [[code(/etc/gitconfig)]]을 찾고, 다음으로 [[code(~/.gitconfig)]] 순서로 찾는다. ==== editor 변경 ==== {{{ $ git config --global core.editor [editor경로] }}} ex) {{{ $ git config --global core.editor vim }}} ==== CRLF 문제 ==== https://www.lesstif.com/pages/viewpage.action?pageId=20776404 2줄 요약 * CORE.EOL * {{{{color:red}core.eol = native}}} 기본 설정. 시스템에서 line ending 을 처리하는 방법에 따른다. windows에서는 CRLF 를 사용하고 Linux, OS X 는 LF 만 사용한다. * {{{{color:red}core.eol = crlf}}} CRLF 를 line ending 으로 사용한다. * {{{{color:red}core.eol = lf}}} LF를 line ending 으로 사용한다. * CORE.AUTOCRLF * {{{{color:red}core.autocrlf = false}}} 기본 설정이다. 파일에 CRLF 를 썼든 LF 를 썼든 git 은 상관하지 않고 파일 그대로 checkin, checkout 한다. 이 설정은 line ending 이 다른 OS 에서는 text file 이 변경되었다고 나오므로 위에서 언급한 여러 가지 문제가 발생할 수 있다. * {{{{color:red}core.autocrlf = true}}} text file을 object database 에 넣기전에 CRLF 를 LF 로 변경한다. * {{{{color:red}core.autocrlf = input}}} LF를 line ending 으로 사용한다. {{{ ## 설정 $ git config --global core.eol native ## 설정 확인 $ git config --global --list|grep core.eol }}} === 기타 === ==== git 파일이나 폴더 이름 변경 ==== {{{ # git mv oldName newName }}} git 으로 버전 관리할 경우 파일이나 폴더의 이름 변경도 추적할 수 있어야 한다. 특히 리팩토링시 클래스나 패키지 폴더의 이름 변경은 자주 발생하는 작업이므로 변경 내역을 잘 관리해야 한다. ` 변경 사항을 추적하기 어려워지니 절대 삭제후 add 하지 마십시오.` `-n( --dry-run)` 옵션을 사용하면 적용전에 어떻게 변경되는지 테스트가 가능하다. ==== fixup ==== [[html(

오늘 배운 유용한 git command `fixup`
1. 변경사항 A 커밋!
2. 변경사항 B 커밋!
3. 미처 A에 포함시키지 못한 변경사항 AA 발견!
4. git add AA
4. git commit --fixup=A

— Jbee🐝 (@JbeeLjyhanll) January 2, 2022
)]] ==== cherry-pick 중 conflicts 해결 ==== 1. conflict 발생 파일 수정 2. Merge 상태 제거(reset) 후 add stash 하는 방법도 있지만 이 방법이 가장 쉬운 방법이다. [[code(git reset [filename])]] [[code(git add [filename])]] ==== gerrit에 push 할 때 unpacker error 발생 시 ==== unpacker error는 --no-thin 옵션으로 packing을 하지 않고 push 하면 진행될 수 있다. [[code(git push origin HEAD:refs/for/master --no-thin)]] ==== .gitignore ==== ===== Visual Studio ===== https://github.com/github/gitignore/blob/master/VisualStudio.gitignore (※ [[code(.gitignore)]]는 확장자가 아니다. 오직 [[code(.gitignore)]] 파일만 적용 된다.) ==== Passing ssh options to git clone ==== * run git clone without checking the repository host's key {{{ $ git config core.sshCommand 'ssh -o StrictHostKeyChecking=no' }}} ==== Emoji for GitHub ==== http://www.emoji-cheat-sheet.com/ Emoji emoticons listed on this page are supported on Campfire, GitHub, Basecamp, Redbooth, Trac, Flowdock, Sprint.ly, Kandan, Textbox.io, Kippt, Redmine, JabbR, Trello, Hall, Plug.dj, Qiita, Zendesk, Ruby China, Grove, Idobata, NodeBB Forums, Slack, Streamup, OrganisedMinds, Hackpad, Cryptbin, Kato, Reportedly, Cheerful Ghost, IRCCloud, Dashcube, MyVideoGameList, Subrosa, Sococo, Quip, And Bang, Bonusly, Discourse, Ello, Twemoji Awesome, Got Chosen, Flow, ReadMe.io, esa, DBook, Groups.io, TeamworkChat, Damn Bugs, Let's Chat, Buildkite, ChatGrape, Dokuwiki, Usersnap, Discord, Status Hero, Bitbucket, Gitter, and YouTube. ==== GUI Clients ==== https://git-scm.com/downloads/guis/ ---- CategoryDev