궁금한게 많은 개발자 노트

[ Github ] 자주 사용하는 Github 명령어 본문

Language

[ Github ] 자주 사용하는 Github 명령어

궁금한게 많은 개발자 2020. 7. 1. 14:48

[ Git Branch 이름 변경 ]
git branch를 생성하고 checkout을 통해 HEAD를 옮긴 후 작업을 진행하다가 뭔가 내가 작업한 내용과
branch의 이름이 일관성이 없다고 느껴질 때, 내용을 다른 branch로 옮길 수 없으니 branch이름만 변경시에 사용!

git branch -m prev_branch_name new_branch_name

 


[ Git Add 취소 ]

git repository에 올리기 위해 수정한 파일들을 commit될 수 있는 상태로 add 명령어로
stage area에 이미 올렸는데, 해당 commit에 포함되지 말아야할 파일을 add했을 경우 unstage하고 싶은 경우 사용

// 모든 파일들을 stage상태로 변경
$ git add *

// 파일들의 상태를 확인한다.
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   staged files...

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	unstaged files...

위와 같이 git add * 명령어를 사용하여 해당 commit에 올릴 파일들 이외에도 모든 파일을들 stage로 올렸을경우,
아래 명령어를 통해 unstage로 보낼 수 있다. HEAD를 붙여도 되고 안붙여도 되는데 현재 commit될 가장 최신의
상태에서 제한다는 의미로 default이므로 생략가능

git reset HEAD file_name

git reset file_name

 

[ Git Commit 취소 ]
작업 내용을 commit 후 push 하려고 보니, 불필요한 file이 commit에 포함되어 있다던지
commit message를 수정하고 싶은 경우 commit을 취소 후 수정이 필요한 경우가 있다.

우선 git log명령어를 통해 잘못들어간 commit id를 확인하거나 가장 최신 commit인 HEAD로 부터
몇번째 commit인지를 확인한다.

commit 7c8387323aca3fc3a9d0ce506ce76146c55fd6c2 (HEAD -> master, upstream/master, origin/master)
Author: ks1171-park <ks1171.park@email.com>
Date:   Fri Jun 26 17:19:34 2020 +0900

    show_diagnostics: Changed the order of json columns
    
    Signed-off-by: ks1171-park <ks1171.park@email.com>

commit 96979ee32279426dbae967c455e04348b7e3dac5
Author: ks1171-park <ks1171.park@email.com>
Date:   Wed Jun 24 13:15:52 2020 +0900

    diagnostics: Implement python script to show diagnostic msg list
    
    Signed-off-by: ks1171-park <ks1171.park@email.com>

commit 7db942ba2dc86ec54a5acdd24fbfa106ba14efa2
...

위의 경우에 가장 상위 commit을 취소하고 싶은 경우, git reset HEAD^를 사용하거나 git reset commit-id를 사용

// 동일한 명령
git reset HEAD^
git reset 7c8387323aca3fc3a9d0ce506ce76146c55fd6c2

// 최근 2개의 commit을 되돌리고 싶은 경우
git reset HEAD~2
git reset 96979ee32279426dbae967c455e04348b7e3dac5

reset 명령어에는 option을 줄 수가 있는데, soft, mixed, hard 3가지 종류가 있다.
soft의 경우 commit을 취소하면서 변경사항에 해당되는 파일들을 staged 상태로 둔다.
mixed의 경우는 default이며, commit을 취소하면서 변경사항에 해당하는 파일들을 unstaged로 돌린다.
hard의 경우는 commit을 취소하면서 변경사항에 해당하는 파일들의 수정사항도 이전으로 돌린다. (#주의)

git reset --hard HEAD^

 

[ Git Commit message 변경 ]
가장 상위 commit의 message만 수정하고자 하는경우는 간단하다.

git commit --amend

 

[ Git Commit 수정 ]
방금 올린 commit을 수정하거나 취소하는 경우에는 간단히 위처럼 reset이나 amend옵션을 통해 간단히 해결가능.
하지만, 여러 commit이 쌓이고 나서 중간 commit에서 실수를 발견했을때는 그 수정과정이 만만치 않다.

처음 그런 경우를 직면했을때, 아는것이 reset밖에 없었기 때문에 5개의 commit을 한 PR(pull request)로 올리고
3번째 commit에서 수정을 해야하는 경우 5개의 commit를 다 되돌리고 다시 1,2번째 수정사항을 add, commit후
3번째 commit전에 수정사항 반영 후 다시 3,4,5의 commit 후 올리는 작업을 반복했다.
( 그래서 중간 commit에 대해 리뷰해주시는 경우에 너무 무서웠다 )

그런데 그런 작업을 하고있을 때, 지나가다 보시고는 rebase라는 것을 사용하면 그렇게하지 않아도 된다고
말씀해주시고 똑같은 작업을 이렇게도 할 수있다고 보여주셨다. 충격적으로 효율적이였다.
대략적인 흐름은 아래와 같다.

git rebase --interactive <commit-id>^ 

change pick -> edit & save 

<make changes> 

git add file_name

git commit --all --amend --no-edit		// 같은 commit message로 넣을 경우 

git rebase --continue 					// rebase를 끝마친다는 의미

git push -f origin master				// 중간 commit만 변경된 상태로 force push

git rebase -i옵션이나 --interactive 옵션을 사용하고 수정하고자하는 commit-id뒤에 ^를 붙여준다.
이는 가장 최신의 commit부터 수정하고자하는 commit-id번째까지 포함해서 list중에 commit을 고치겠다는 의미

git rebase --interactive 96979ee32279426dbae967c455e04348b7e3dac5^


↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓


pick 96979ee diagnostics: Implement python script to show diagnostic msg list
pick 5ca1cf7 show_diagnostics: Changed the order of json columns

# Rebase 7db942b..5ca1cf7 onto 7db942b (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

아까 git log를 통해 확인한 두번째 commit-id를 이용하여 rebase 한 결과이다.
pick이라고 되어있는 의미는 내가 고칠 수 있는 commit 들의 리스트를 선택한 결과이고
이것을 edit으로 바꾸면 해당 commit을 고치겠다는 의미!
두번째 commit을 변경한다고 생각하고 pick을 지우고 edit 을 입력한다음 저장

Stopped at 5ca1cf7...  show_diagnostics: Changed the order of json columns
You can amend the commit now, with

  git commit --amend 

Once you are satisfied with your changes, run

  git rebase --continue

그러고 나면 위의 메세지를 확인할 수 있다.
현재 5ca1cf7...의 commit에서 멈췄고 해당 commit을 수정할 수 있으며 수정후
git rebase --continue를 해주면 해당 변경사항이 두번째 commit에 반영

이제 수정할 부분들을 수정하고 원래 하던대로 git add -> git commit한 다음 git rebase --continue로 rebase종료!

이 때, 주의할점은 rebase후에는 수정한 commit의 commit-id가 변경된다.
이 점을 유의해두고 신중히 사용하여야 하며, 잘만 사용한다면 정말 유용한 명령어이다.
아마 내가 제일 많이 사용하는 명령어가 아닐까 싶다.

rebase 종료 후, 변경사항을 다시 PR에 반영하기 위해서는 git push origin branch -f옵션을 사용하여 force push
force push는 이미 PR이 올라간다음 수정사항을 반영할때 유용하지만 이도 마찬가지로 주의하여 사용!

 

[ Pull Request를 내 branch에 반영 ]
다른 분들과 함께 업무를 하다보면, 다른 사람이 올린 PR을 리뷰해야할 경우도 생기고, 
리뷰를 하려다보면 그것을 반영하여 잘 동작하는지 확인하고 싶은 경우가 있다.

그런 경우, 변경된 파일의 내용을 복사해와서 HEAD branch에 붙여넣기 한 다음 저장 후 테스트?
이것은 좀 아닌것 같다. 수정된 파일이 한두개가 아니고 연속된 line이 아니라면?

여기서 git pull 명령어가 사용되는데 보통 upstream remote에서 변경사항을 내려받을 때 사용할 것이다.
지금의 경우에도 마찬가지로 PR은 보통 origin remote에서 commit -> push후 upstream으로
pull request를 올리게 되는 구조일것이다.

그러므로 upstream remote에 올라간 PR을 내려받기 위해서 아래의 명령어를 사용
git pull remote-name pull/PR번호/head --rebase

git pull upstream pull/(PR번호)/head --rebase

upstream remote에 올라간 PR번호에 해당하는 내용을 head에 내려받으면서 그것을 head로 변경하는 rebase진행!
그 후 git log명령어로 확인해보면 head commit이 PR에 올라간 내용이 된다.
즉, PR을 올린 개발자의 환경과 같은 상황으로 rebase 되었으므로 코드리뷰 및 테스트가 용이하게 될것이다.
 

 

[ Git reset 취소 ]
reset을 통해 commit을 취소했는데, 잘못된 commit-id나 잘못된 HEAD~N를 사용하여 reset을 취소하고 싶은경우
git reset --hard옵션을 사용하여 작성한 코드까지 날아간 경우 정말 당황할 수 있다.


이때는 git reflog를 통해 이제껏 사용한 git 명령어의 이력을 확인해야 한다.
가장 최근에 입력한 git 명령어부터 0 index로 시작하여 아래로 쭉 사용해온 이력들이 나오게 된다.

$ git reflog
85e6898 (HEAD -> reboot) HEAD@{0}: commit (amend): Modify the result value when auto reboot is possible
bb333b3 (origin/reboot) HEAD@{1}: rebase -i (finish): returning to refs/heads/reboot
bb333b3 (origin/reboot) HEAD@{2}: rebase -i (pick): Modify the result value when auto reboot is possible
340059c HEAD@{3}: commit (amend): Implement manual pop-up guide dialog when auto reboot is impossible
fffd31e HEAD@{4}: rebase -i: fast-forward
664038c (upstream/master, origin/master, origin/HEAD, master) HEAD@{5}: rebase -i (start): checkout fffd31ed26903732f5a07faeeca3f72d46b6ba68^
...

( 위의 경우에는 reset으로 잘못 실수한 경우의 reflog는 아니다 )

당황하지말고, 찬찬히 읽어보면 가장 최근인 HEAD@{0}부근에서 reset을 통해 내가 실수한 부분을 찾을 수 있다.
해당 index를 확인하여 아래의 명령어를 사용하면 다시 해당 명령어를 사용하기 전 상태로 복구!

git reset --hard HEAD@{index}

 

 

앞으로 업무를 진행하면서 더 유용한 github tip이 있다면 추가업로드 할 것이다.
github은 복잡해 보이지만, 알고나면 손쉽고 정말 간편한 기능들이 많이 있으므로.. 아는것이 힘인것 같다.

Comments